V10
This commit is contained in:
parent
ec17506c33
commit
727b6fcf29
@ -10,20 +10,20 @@ if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== tru
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin Panel</title>
|
||||
<title>Admin Dashboard</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="index.php">Admin Panel</a>
|
||||
<a class="navbar-brand" href="index.php">Admin Dashboard</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" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">Restaurants</a>
|
||||
<a class="nav-link" href="index.php">Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="orders.php">Orders</a>
|
||||
|
||||
@ -9,12 +9,86 @@ if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== tru
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("SELECT id, name, cuisine FROM restaurants ORDER BY name");
|
||||
$restaurants = $stmt->fetchAll();
|
||||
|
||||
// Analytics Queries
|
||||
// Total Revenue
|
||||
$stmt_revenue = $pdo->prepare("SELECT SUM(total_price) as total_revenue FROM orders WHERE status = ?");
|
||||
$stmt_revenue->execute(['completed']);
|
||||
$total_revenue = $stmt_revenue->fetchColumn();
|
||||
|
||||
// Total Orders
|
||||
$total_orders = $pdo->query("SELECT COUNT(*) FROM orders")->fetchColumn();
|
||||
|
||||
// Total Customers
|
||||
$total_customers = $pdo->query("SELECT COUNT(*) FROM users WHERE role = 'customer'")->fetchColumn();
|
||||
|
||||
// Most Popular Restaurants
|
||||
$stmt_popular = $pdo->query("
|
||||
SELECT r.name, COUNT(o.id) as order_count
|
||||
FROM restaurants r
|
||||
JOIN orders o ON r.id = o.restaurant_id
|
||||
GROUP BY r.id
|
||||
ORDER BY order_count DESC
|
||||
LIMIT 5
|
||||
");
|
||||
$popular_restaurants = $stmt_popular->fetchAll();
|
||||
|
||||
// Fetch all restaurants for the management table
|
||||
$stmt_restaurants = $pdo->query("SELECT id, name, cuisine FROM restaurants ORDER BY name");
|
||||
$restaurants = $stmt_restaurants->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Restaurant Management</h2>
|
||||
<h2>Admin Dashboard</h2>
|
||||
|
||||
<!-- Analytics Cards -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-primary mb-3">
|
||||
<div class="card-header">Total Revenue</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">$<?php echo number_format($total_revenue, 2); ?></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-info mb-3">
|
||||
<div class="card-header">Total Orders</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?php echo $total_orders; ?></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card text-white bg-success mb-3">
|
||||
<div class="card-header">Total Customers</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?php echo $total_customers; ?></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Most Popular Restaurants
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php foreach ($popular_restaurants as $restaurant): ?>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<?php echo htmlspecialchars($restaurant['name']); ?>
|
||||
<span class="badge bg-primary rounded-pill"><?php echo $restaurant['order_count']; ?> orders</span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="mt-5">Restaurant Management</h2>
|
||||
<p><a href="add_restaurant.php" class="btn btn-success">Add New Restaurant</a></p>
|
||||
|
||||
<table class="table table-striped">
|
||||
@ -41,4 +115,4 @@ $restaurants = $stmt->fetchAll();
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
<?php include 'footer.php'; ?>
|
||||
|
||||
29
api/get_order_status.php
Normal file
29
api/get_order_status.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
session_start();
|
||||
require_once '../db/config.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(['error' => 'Unauthorized']);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!isset($_GET['order_id'])) {
|
||||
echo json_encode(['error' => 'No order ID specified']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$order_id = $_GET['order_id'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
// Fetch order status, ensuring the user owns the order
|
||||
$stmt = $db->prepare("SELECT status FROM orders WHERE id = ? AND user_id = ?");
|
||||
$stmt->execute([$order_id, $user_id]);
|
||||
$order = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($order) {
|
||||
echo json_encode(['status' => $order['status']]);
|
||||
} else {
|
||||
echo json_encode(['error' => 'Order not found or permission denied']);
|
||||
}
|
||||
?>
|
||||
@ -2,26 +2,28 @@
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['coupon_code'])) {
|
||||
if (isset($_POST['coupon_code']) && !empty($_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();
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM coupons WHERE code = ? AND is_active = 1");
|
||||
$stmt->execute([$coupon_code]);
|
||||
$coupon = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($coupon) {
|
||||
$_SESSION['coupon'] = [
|
||||
'id' => $coupon['id'],
|
||||
'code' => $coupon['code'],
|
||||
'discount_percentage' => $coupon['discount_percentage']
|
||||
];
|
||||
$_SESSION['coupon_id'] = $coupon['id'];
|
||||
$_SESSION['coupon_code'] = $coupon['code'];
|
||||
$_SESSION['discount_percentage'] = $coupon['discount_percentage'];
|
||||
unset($_SESSION['coupon_error']);
|
||||
} else {
|
||||
$_SESSION['coupon_error'] = "Invalid or expired coupon code.";
|
||||
unset($_SESSION['coupon']);
|
||||
unset($_SESSION['coupon_id']);
|
||||
unset($_SESSION['coupon_code']);
|
||||
unset($_SESSION['discount_percentage']);
|
||||
}
|
||||
} else {
|
||||
$_SESSION['coupon_error'] = "Please enter a coupon code.";
|
||||
}
|
||||
|
||||
header('Location: cart.php');
|
||||
exit;
|
||||
header("Location: cart.php");
|
||||
exit();
|
||||
@ -807,3 +807,75 @@ footer {
|
||||
.search-button:hover {
|
||||
background-color: #ff4f4f;
|
||||
}
|
||||
|
||||
/* Filter Bar */
|
||||
.filter-bar {
|
||||
margin-top: 1.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filter-dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.filter-button {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
color: var(--white);
|
||||
padding: 12px 24px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
border-color: var(--white);
|
||||
}
|
||||
|
||||
.filter-button-icon {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-options {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: var(--white);
|
||||
min-width: 200px;
|
||||
box-shadow: var(--shadow-soft);
|
||||
border-radius: var(--border-radius);
|
||||
z-index: 1;
|
||||
margin-top: 8px;
|
||||
padding: 8px 0;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.filter-option {
|
||||
color: var(--text-color);
|
||||
padding: 12px 20px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.filter-option:hover, .filter-option.active {
|
||||
background-color: var(--light-gray);
|
||||
color: var(--coral);
|
||||
}
|
||||
|
||||
.filter-dropdown:hover .filter-options {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.filter-dropdown:hover .filter-button-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
@ -95,4 +95,22 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Filter dropdown
|
||||
const filterDropdown = document.querySelector('.filter-dropdown');
|
||||
if (filterDropdown) {
|
||||
const filterButton = filterDropdown.querySelector('.filter-button');
|
||||
const filterOptions = filterDropdown.querySelector('.filter-options');
|
||||
|
||||
filterButton.addEventListener('click', () => {
|
||||
const isVisible = filterOptions.style.display === 'block';
|
||||
filterOptions.style.display = isVisible ? 'none' : 'block';
|
||||
});
|
||||
|
||||
window.addEventListener('click', (event) => {
|
||||
if (!filterDropdown.contains(event.target)) {
|
||||
filterOptions.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
BIN
assets/pasted-20251015-030330-76b11093.png
Normal file
BIN
assets/pasted-20251015-030330-76b11093.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 318 KiB |
38
cart.php
38
cart.php
@ -69,21 +69,29 @@ include 'header.php';
|
||||
</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'];
|
||||
<?php
|
||||
$discount_amount = 0;
|
||||
$final_total = $totalPrice;
|
||||
|
||||
if (isset($_SESSION['coupon_code']) && isset($_SESSION['discount_percentage'])) {
|
||||
$discount_percentage = $_SESSION['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; ?>
|
||||
$final_total = $totalPrice - $discount_amount;
|
||||
?>
|
||||
<h5 class="text-success">Discount (<?php echo htmlspecialchars($_SESSION['coupon_code']); ?> @ <?php echo $discount_percentage; ?>%): -$<?php echo number_format($discount_amount, 2); ?></h5>
|
||||
<h3>Total: $<?php echo number_format($final_total, 2); ?></h3>
|
||||
<a href="remove_coupon.php" class="btn btn-danger btn-sm mt-2">Remove Coupon</a>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<h3>Total: $<?php echo number_format($final_total, 2); ?></h3>
|
||||
<?php
|
||||
}
|
||||
|
||||
$_SESSION['total_price'] = $final_total;
|
||||
$_SESSION['discount_amount'] = $discount_amount;
|
||||
$_SESSION['subtotal'] = $totalPrice;
|
||||
?>
|
||||
<a href="checkout.php" class="btn btn-primary mt-3">Proceed to Checkout</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -95,4 +103,4 @@ include 'header.php';
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php require_once 'footer.php'; ?>
|
||||
<?php require_once 'footer.php'; ?>
|
||||
@ -1,69 +1,39 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
require_once 'db/config.php';
|
||||
require_once 'includes/api_keys.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header("Location: checkout.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
\Stripe\Stripe::setApiKey($stripeSecretKey);
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$pdo = db();
|
||||
$total_price = $_SESSION['total_price'] ?? 0;
|
||||
$coupon_id = $_SESSION['coupon_id'] ?? null;
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
|
||||
// Fetch cart items
|
||||
$stmt = $pdo->prepare("SELECT mi.name, mi.price, c.quantity FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
$cart_items = $stmt->fetchAll();
|
||||
|
||||
if (empty($cart_items)) {
|
||||
if ($total_price <= 0) {
|
||||
header("Location: cart.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
$line_items = [];
|
||||
foreach ($cart_items as $item) {
|
||||
$line_items[] = [
|
||||
$checkout_session = \Stripe\Checkout\Session::create([
|
||||
'payment_method_types' => ['card'],
|
||||
'line_items' => [[
|
||||
'price_data' => [
|
||||
'currency' => 'usd',
|
||||
'product_data' => [
|
||||
'name' => $item['name'],
|
||||
'name' => 'Total Order Amount',
|
||||
],
|
||||
'unit_amount' => $item['price'] * 100, // Price in cents
|
||||
'unit_amount' => $total_price * 100, // Amount in cents
|
||||
],
|
||||
'quantity' => $item['quantity'],
|
||||
];
|
||||
}
|
||||
|
||||
// Add delivery fee
|
||||
$delivery_fee = 5.00;
|
||||
$line_items[] = [
|
||||
'price_data' => [
|
||||
'currency' => 'usd',
|
||||
'product_data' => [
|
||||
'name' => 'Delivery Fee',
|
||||
],
|
||||
'unit_amount' => $delivery_fee * 100,
|
||||
],
|
||||
'quantity' => 1,
|
||||
];
|
||||
|
||||
|
||||
$checkout_session = \Stripe\Checkout\Session::create([
|
||||
'payment_method_types' => ['card'],
|
||||
'line_items' => $line_items,
|
||||
'quantity' => 1,
|
||||
]],
|
||||
'mode' => 'payment',
|
||||
'success_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-cancel.php',
|
||||
'success_url' => 'http://localhost:8080/payment-success.php?session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => 'http://localhost:8080/payment-cancel.php',
|
||||
'metadata' => [
|
||||
'user_id' => $user_id,
|
||||
'coupon_id' => $coupon_id
|
||||
]
|
||||
]);
|
||||
|
||||
header("HTTP/1.1 303 See Other");
|
||||
header("Location: " . $checkout_session->url);
|
||||
header("Location: " . $checkout_session->url);
|
||||
@ -19,12 +19,7 @@ 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';
|
||||
@ -53,6 +48,7 @@ session_start();
|
||||
<?php if (isset($_SESSION['user_id'])): ?>
|
||||
<span>Welcome, <?php echo htmlspecialchars($_SESSION['user_name']); ?></span>
|
||||
<a href="profile.php">My Profile</a>
|
||||
<a href="order_history.php">Order History</a>
|
||||
<a href="logout.php">Logout</a>
|
||||
<?php else: ?>
|
||||
<a href="login.php">Login</a>
|
||||
|
||||
34
index.php
34
index.php
@ -4,22 +4,28 @@
|
||||
<section class="hero">
|
||||
<div class="hero-content">
|
||||
<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']) : '' ?>">
|
||||
<form action="search.php" method="get" class="search-form">
|
||||
<input type="text" name="query" class="search-bar" placeholder="Search for restaurants, cuisines..." required>
|
||||
<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):
|
||||
?>
|
||||
<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 class="filter-bar">
|
||||
<div class="filter-dropdown">
|
||||
<button class="filter-button">
|
||||
<span class="filter-button-text"><?= isset($_GET['cuisine']) && $_GET['cuisine'] != '' ? htmlspecialchars($_GET['cuisine']) : 'All Cuisines' ?></span>
|
||||
<span class="filter-button-icon">▼</span>
|
||||
</button>
|
||||
<div class="filter-options">
|
||||
<a href="index.php<?= isset($_GET['search']) ? '?search=' . urlencode($_GET['search']) : '' ?>" class="filter-option <?= !isset($_GET['cuisine']) || $_GET['cuisine'] == '' ? 'active' : '' ?>">All Cuisines</a>
|
||||
<?php
|
||||
$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):
|
||||
?>
|
||||
<a href="index.php?cuisine=<?= htmlspecialchars($cuisine) ?><?= $search_param ?>" class="filter-option <?= (isset($_GET['cuisine']) && $_GET['cuisine'] == $cuisine) ? 'active' : '' ?>"><?= htmlspecialchars($cuisine) ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
1
migrations/20251015_add_role_to_users.sql
Normal file
1
migrations/20251015_add_role_to_users.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE users ADD COLUMN role VARCHAR(255) NOT NULL DEFAULT 'customer';
|
||||
2
migrations/20251015_add_user_id_to_restaurants.sql
Normal file
2
migrations/20251015_add_user_id_to_restaurants.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE restaurants ADD COLUMN user_id INT NULL;
|
||||
ALTER TABLE restaurants ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
56
order_history.php
Normal file
56
order_history.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
include 'header.php';
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$db = db();
|
||||
|
||||
$stmt = $db->prepare("SELECT * FROM orders WHERE user_id = ? ORDER BY order_date DESC");
|
||||
$stmt->execute([$user_id]);
|
||||
$orders = $stmt->fetchAll();
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2>My Order History</h2>
|
||||
<hr>
|
||||
|
||||
<?php if (empty($orders)): ?>
|
||||
<div class="alert alert-info">You have not placed any orders yet.</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order ID</th>
|
||||
<th>Date</th>
|
||||
<th>Total</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($orders as $order): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($order['id']); ?></td>
|
||||
<td><?php echo htmlspecialchars(date('F j, Y, g:i a', strtotime($order['order_date']))); ?></td>
|
||||
<td>$<?php echo htmlspecialchars(number_format($order['total_price'], 2)); ?></td>
|
||||
<td><?php echo htmlspecialchars(ucfirst($order['status'])); ?></td>
|
||||
<td>
|
||||
<a href="order_details.php?id=<?php echo $order['id']; ?>" class="btn btn-primary btn-sm">View Details</a>
|
||||
<a href="order_status.php?order_id=<?php echo $order['id']; ?>" class="btn btn-info btn-sm">Track Order</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
123
order_status.php
Normal file
123
order_status.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
include 'header.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!isset($_GET['order_id'])) {
|
||||
echo "<div class='container mt-5'><p>No order specified.</p></div>";
|
||||
include 'footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
$order_id = $_GET['order_id'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
// Fetch order details to ensure the user owns this order
|
||||
$p_order = $db->prepare("SELECT o.*, r.name as restaurant_name FROM orders o JOIN restaurants r ON o.restaurant_id = r.id WHERE o.id = ? AND o.user_id = ?");
|
||||
$p_order->execute([$order_id, $user_id]);
|
||||
$order = $p_order->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$order) {
|
||||
echo "<div class='container mt-5'><p>Order not found or you do not have permission to view it.</p></div>";
|
||||
include 'footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch order items
|
||||
$p_items = $db->prepare("SELECT oi.*, mi.name as item_name FROM order_items oi JOIN menu_items mi ON oi.menu_item_id = mi.id WHERE oi.order_id = ?");
|
||||
$p_items->execute([$order_id]);
|
||||
$items = $p_items->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2>Order Status for #<?php echo $order['id']; ?></h2>
|
||||
<hr>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Live Status</h5>
|
||||
<p><strong>Restaurant:</strong> <?php echo htmlspecialchars($order['restaurant_name']); ?></p>
|
||||
<p><strong>Order Date:</strong> <?php echo date("F j, Y, g:i a", strtotime($order['created_at'])); ?></p>
|
||||
<div id="order-status-container">
|
||||
<p><strong>Status:</strong> <span class="badge bg-primary fs-6" id="order-status"><?php echo htmlspecialchars($order['status']); ?></span></p>
|
||||
</div>
|
||||
<div class="progress" style="height: 25px;">
|
||||
<div id="progress-bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Order Summary</h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php foreach ($items as $item): ?>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<?php echo htmlspecialchars($item['item_name']); ?> (x<?php echo $item['quantity']; ?>)
|
||||
<span>$<?php echo number_format($item['price'] * $item['quantity'], 2); ?></span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<strong>Total</strong>
|
||||
<strong>$<?php echo number_format($order['total_price'], 2); ?></strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a href="order_history.php" class="btn btn-secondary mt-3">Back to Order History</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const orderId = <?php echo $order_id; ?>;
|
||||
const statusElement = document.getElementById('order-status');
|
||||
const progressBar = document.getElementById('progress-bar');
|
||||
|
||||
const statusToProgress = {
|
||||
'Pending': 10,
|
||||
'In Progress': 40,
|
||||
'Out for Delivery': 75,
|
||||
'Delivered': 100,
|
||||
'Cancelled': 0
|
||||
};
|
||||
|
||||
function updateProgress(status) {
|
||||
const progress = statusToProgress[status] || 0;
|
||||
progressBar.style.width = progress + '%';
|
||||
progressBar.textContent = status;
|
||||
|
||||
if (status === 'Delivered') {
|
||||
progressBar.classList.remove('progress-bar-animated', 'bg-primary');
|
||||
progressBar.classList.add('bg-success');
|
||||
} else if (status === 'Cancelled') {
|
||||
progressBar.classList.remove('progress-bar-animated', 'bg-primary');
|
||||
progressBar.classList.add('bg-danger');
|
||||
} else {
|
||||
progressBar.classList.remove('bg-success', 'bg-danger');
|
||||
progressBar.classList.add('bg-primary', 'progress-bar-animated');
|
||||
}
|
||||
}
|
||||
|
||||
function fetchStatus() {
|
||||
fetch(`api/get_order_status.php?order_id=${orderId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status && data.status !== statusElement.textContent) {
|
||||
statusElement.textContent = data.status;
|
||||
updateProgress(data.status);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error fetching status:', error));
|
||||
}
|
||||
|
||||
updateProgress(statusElement.textContent);
|
||||
setInterval(fetchStatus, 10000); // Poll every 10 seconds
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
@ -4,27 +4,30 @@ require_once 'db/config.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
require_once 'includes/api_keys.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!isset($_GET['session_id'])) {
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
$stripe_session_id = $_GET['session_id'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$pdo = db();
|
||||
|
||||
\Stripe\Stripe::setApiKey($stripeSecretKey);
|
||||
|
||||
try {
|
||||
$checkout_session = \Stripe\Checkout\Session::retrieve($stripe_session_id);
|
||||
$metadata = $checkout_session->metadata;
|
||||
$user_id = $metadata->user_id;
|
||||
$coupon_id = $metadata->coupon_id;
|
||||
|
||||
if ($checkout_session->payment_status == 'paid') {
|
||||
// Fetch cart items and delivery details
|
||||
// Fetch user's address
|
||||
$stmt = $pdo->prepare("SELECT address FROM users WHERE id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
$user = $stmt->fetch();
|
||||
$delivery_address = $user ? $user['address'] : 'N/A';
|
||||
|
||||
// Fetch cart items
|
||||
$stmt = $pdo->prepare("SELECT c.*, mi.price, mi.restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
$cart_items = $stmt->fetchAll();
|
||||
@ -36,16 +39,11 @@ try {
|
||||
|
||||
$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'];
|
||||
$delivery_address = $cart_items[0]['delivery_address'];
|
||||
$delivery_phone = $cart_items[0]['delivery_phone'];
|
||||
$restaurant_id = $cart_items[0]['restaurant_id']; // Assuming order from one restaurant
|
||||
|
||||
// Create order
|
||||
$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]);
|
||||
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_address, coupon_id, discount_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $stripe_session_id, $delivery_address, $coupon_id, $discount_amount]);
|
||||
$order_id = $pdo->lastInsertId();
|
||||
|
||||
// Insert order items
|
||||
@ -58,6 +56,15 @@ try {
|
||||
$stmt = $pdo->prepare("DELETE FROM cart WHERE user_id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
|
||||
// Clear coupon session variables
|
||||
unset($_SESSION['coupon_id']);
|
||||
unset($_SESSION['coupon_code']);
|
||||
unset($_SESSION['discount_percentage']);
|
||||
unset($_SESSION['total_price']);
|
||||
unset($_SESSION['discount_amount']);
|
||||
unset($_SESSION['subtotal']);
|
||||
|
||||
|
||||
$_SESSION['order_id'] = $order_id;
|
||||
header("Location: order_confirmation.php");
|
||||
exit();
|
||||
@ -71,4 +78,4 @@ try {
|
||||
error_log($e->getMessage());
|
||||
header("Location: payment-cancel.php");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,6 +56,12 @@ $details = json_decode($result);
|
||||
if (isset($details->status) && $details->status == 'COMPLETED') {
|
||||
$pdo = db();
|
||||
|
||||
// Fetch user's address
|
||||
$stmt = $pdo->prepare("SELECT address FROM users WHERE id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
$user = $stmt->fetch();
|
||||
$delivery_address = $user ? $user['address'] : 'N/A';
|
||||
|
||||
// Fetch cart items
|
||||
$stmt = $pdo->prepare("SELECT c.*, mi.price, mi.restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
@ -68,19 +74,12 @@ if (isset($details->status) && $details->status == 'COMPLETED') {
|
||||
|
||||
$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) {
|
||||
$restaurant_id = $item['restaurant_id'];
|
||||
}
|
||||
|
||||
$delivery_name = $_POST['name'];
|
||||
$delivery_address = $_POST['address'];
|
||||
$delivery_phone = $_POST['phone'];
|
||||
$coupon_id = $_SESSION['coupon_id'] ?? null;
|
||||
$restaurant_id = $cart_items[0]['restaurant_id']; // Assuming order from one restaurant
|
||||
|
||||
// Create order
|
||||
$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]);
|
||||
$stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_address, coupon_id, discount_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $orderID, $delivery_address, $coupon_id, $discount_amount]);
|
||||
$order_id = $pdo->lastInsertId();
|
||||
|
||||
// Insert order items
|
||||
@ -93,10 +92,18 @@ if (isset($details->status) && $details->status == 'COMPLETED') {
|
||||
$stmt = $pdo->prepare("DELETE FROM cart WHERE user_id = ?");
|
||||
$stmt->execute([$user_id]);
|
||||
|
||||
// Clear coupon session variables
|
||||
unset($_SESSION['coupon_id']);
|
||||
unset($_SESSION['coupon_code']);
|
||||
unset($_SESSION['discount_percentage']);
|
||||
unset($_SESSION['total_price']);
|
||||
unset($_SESSION['discount_amount']);
|
||||
unset($_SESSION['subtotal']);
|
||||
|
||||
$_SESSION['order_id'] = $order_id;
|
||||
echo json_encode(['success' => true]);
|
||||
echo json_encode(['success' => true, 'order_id' => $order_id]);
|
||||
|
||||
} else {
|
||||
error_log('PayPal Capture Failed: ' . print_r($details, true));
|
||||
echo json_encode(['error' => 'Payment failed. Please try again.']);
|
||||
}
|
||||
}
|
||||
26
profile.php
26
profile.php
@ -31,10 +31,7 @@ $p_user = $db->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$p_user->execute([$user_id]);
|
||||
$user = $p_user->fetch();
|
||||
|
||||
// Fetch user's orders
|
||||
$p_orders = $db->prepare("SELECT o.*, r.name as restaurant_name FROM orders o JOIN restaurants r ON o.restaurant_id = r.id WHERE o.user_id = ? ORDER BY o.created_at DESC");
|
||||
$p_orders->execute([$user_id]);
|
||||
$orders = $p_orders->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
@ -64,24 +61,9 @@ $orders = $p_orders->fetchAll(PDO::FETCH_ASSOC);
|
||||
<button type="submit" name="update_profile" class="btn btn-primary">Update Profile</button>
|
||||
</form>
|
||||
|
||||
<h2 class="mt-5">My Orders</h2>
|
||||
<hr>
|
||||
<?php if (count($orders) > 0): ?>
|
||||
<div class="list-group">
|
||||
<?php foreach ($orders as $order): ?>
|
||||
<a href="order_details.php?id=<?php echo $order['id']; ?>" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Order #<?php echo $order['id']; ?> - <?php echo htmlspecialchars($order['restaurant_name']); ?></h5>
|
||||
<small><?php echo date("F j, Y, g:i a", strtotime($order['created_at'])); ?></small>
|
||||
</div>
|
||||
<p class="mb-1">Total: $<?php echo number_format($order['total_price'], 2); ?></p>
|
||||
<small>Status: <?php echo htmlspecialchars($order['status']); ?></small>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<p>You have no past orders.</p>
|
||||
<?php endif; ?>
|
||||
<div class="mt-5">
|
||||
<a href="order_history.php" class="btn btn-secondary">View Order History</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
unset($_SESSION['coupon']);
|
||||
unset($_SESSION['coupon_id']);
|
||||
unset($_SESSION['coupon_code']);
|
||||
unset($_SESSION['discount_percentage']);
|
||||
unset($_SESSION['coupon_error']);
|
||||
unset($_SESSION['discount_amount']);
|
||||
|
||||
header('Location: cart.php');
|
||||
exit;
|
||||
header("Location: cart.php");
|
||||
exit();
|
||||
66
restaurant/add_menu_item.php
Normal file
66
restaurant/add_menu_item.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Check if the user is logged in as a restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// Get the restaurant ID associated with the logged-in user
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if (!$restaurant) {
|
||||
// If for some reason the user is a restaurant owner but has no restaurant, redirect them
|
||||
header('Location: ../index.php');
|
||||
exit;
|
||||
}
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = $_POST['name'] ?? '';
|
||||
$description = $_POST['description'] ?? '';
|
||||
$price = $_POST['price'] ?? '';
|
||||
|
||||
if ($name && $price) {
|
||||
$stmt = $pdo->prepare("INSERT INTO menu_items (restaurant_id, name, description, price) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$restaurant_id, $name, $description, $price]);
|
||||
header('Location: menu.php');
|
||||
exit;
|
||||
} else {
|
||||
$error = "Name and price are required.";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Add New Menu Item</h2>
|
||||
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="add_menu_item.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description"></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label">Price</label>
|
||||
<input type="number" step="0.01" class="form-control" id="price" name="price" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Add Item</button>
|
||||
<a href="menu.php" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
32
restaurant/delete_menu_item.php
Normal file
32
restaurant/delete_menu_item.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Check if the user is logged in as a restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$menu_item_id = $_GET['id'] ?? null;
|
||||
|
||||
if ($menu_item_id) {
|
||||
$pdo = db();
|
||||
|
||||
// Get the restaurant ID associated with the logged-in user
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if ($restaurant) {
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
// Delete the menu item only if it belongs to the owner's restaurant
|
||||
$stmt = $pdo->prepare("DELETE FROM menu_items WHERE id = ? AND restaurant_id = ?");
|
||||
$stmt->execute([$menu_item_id, $restaurant_id]);
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: menu.php');
|
||||
exit;
|
||||
?>
|
||||
82
restaurant/edit_menu_item.php
Normal file
82
restaurant/edit_menu_item.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Check if the user is logged in as a restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$menu_item_id = $_GET['id'] ?? null;
|
||||
if (!$menu_item_id) {
|
||||
header('Location: menu.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// Get the restaurant ID associated with the logged-in user
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if (!$restaurant) {
|
||||
header('Location: ../index.php');
|
||||
exit;
|
||||
}
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
// Get the menu item and verify it belongs to the correct restaurant
|
||||
$stmt = $pdo->prepare("SELECT * FROM menu_items WHERE id = ? AND restaurant_id = ?");
|
||||
$stmt->execute([$menu_item_id, $restaurant_id]);
|
||||
$item = $stmt->fetch();
|
||||
|
||||
if (!$item) {
|
||||
// If the item doesn't exist or doesn't belong to this owner, redirect
|
||||
header('Location: menu.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = $_POST['name'] ?? '';
|
||||
$description = $_POST['description'] ?? '';
|
||||
$price = $_POST['price'] ?? '';
|
||||
|
||||
if ($name && $price) {
|
||||
$stmt = $pdo->prepare("UPDATE menu_items SET name = ?, description = ?, price = ? WHERE id = ? AND restaurant_id = ?");
|
||||
$stmt->execute([$name, $description, $price, $menu_item_id, $restaurant_id]);
|
||||
header('Location: menu.php');
|
||||
exit;
|
||||
} else {
|
||||
$error = "Name and price are required.";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Edit Menu Item</h2>
|
||||
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="edit_menu_item.php?id=<?php echo $item['id']; ?>" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($item['name']); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description"><?php echo htmlspecialchars($item['description']); ?></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label">Price</label>
|
||||
<input type="number" step="0.01" class="form-control" id="price" name="price" value="<?php echo htmlspecialchars($item['price']); ?>" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Update Item</button>
|
||||
<a href="menu.php" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
88
restaurant/edit_restaurant.php
Normal file
88
restaurant/edit_restaurant.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Ensure the user is a logged-in restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$owner_id = $_SESSION['user_id'];
|
||||
$pdo = db();
|
||||
|
||||
// Find the restaurant ID managed by the owner
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$owner_id]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if (!$restaurant) {
|
||||
echo "<div class='alert alert-danger'>You are not associated with any restaurant.</div>";
|
||||
include 'footer.php';
|
||||
exit;
|
||||
}
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
// Handle form submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = $_POST['name'] ?? '';
|
||||
$cuisine = $_POST['cuisine'] ?? '';
|
||||
$address = $_POST['address'] ?? '';
|
||||
$phone_number = $_POST['phone_number'] ?? '';
|
||||
$image_url = $_POST['image_url'] ?? '';
|
||||
|
||||
if ($name && $cuisine && $address) {
|
||||
$update_stmt = $pdo->prepare("UPDATE restaurants SET name = ?, cuisine = ?, address = ?, phone_number = ?, image_url = ? WHERE id = ? AND user_id = ?");
|
||||
$update_stmt->execute([$name, $cuisine, $address, $phone_number, $image_url, $restaurant_id, $owner_id]);
|
||||
|
||||
// Redirect to the dashboard with a success message
|
||||
$_SESSION['success_message'] = "Your restaurant details have been updated successfully!";
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} else {
|
||||
$error = "Name, Cuisine, and Address are required fields.";
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch current restaurant details
|
||||
$stmt = $pdo->prepare("SELECT * FROM restaurants WHERE id = ?");
|
||||
$stmt->execute([$restaurant_id]);
|
||||
$restaurant_details = $stmt->fetch();
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Edit Your Restaurant Details</h2>
|
||||
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="edit_restaurant.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Restaurant Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($restaurant_details['name']); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="cuisine" class="form-label">Cuisine Type</label>
|
||||
<input type="text" class="form-control" id="cuisine" name="cuisine" value="<?php echo htmlspecialchars($restaurant_details['cuisine']); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="address" class="form-label">Address</label>
|
||||
<input type="text" class="form-control" id="address" name="address" value="<?php echo htmlspecialchars($restaurant_details['address']); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="phone_number" class="form-label">Phone Number</label>
|
||||
<input type="text" class="form-control" id="phone_number" name="phone_number" value="<?php echo htmlspecialchars($restaurant_details['phone_number']); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="image_url" class="form-label">Image URL</label>
|
||||
<input type="text" class="form-control" id="image_url" name="image_url" value="<?php echo htmlspecialchars($restaurant_details['image_url']); ?>">
|
||||
<small class="form-text text-muted">A URL to a publicly accessible image of your restaurant.</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
<a href="index.php" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
4
restaurant/footer.php
Normal file
4
restaurant/footer.php
Normal file
@ -0,0 +1,4 @@
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
43
restaurant/header.php
Normal file
43
restaurant/header.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['user_role']) || $_SESSION['user_role'] !== 'restaurant_owner') {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Restaurant Dashboard</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="index.php">Restaurant Dashboard</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" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="menu.php">Menu</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="orders.php">Orders</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../logout.php">Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-4">
|
||||
13
restaurant/index.php
Normal file
13
restaurant/index.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php include 'header.php'; ?>
|
||||
|
||||
<h1>Welcome, <?php echo htmlspecialchars($_SESSION['user_name']); ?>!</h1>
|
||||
|
||||
<p>This is your restaurant dashboard. From here you can manage your restaurant's menu, view orders, and update your restaurant's information.</p>
|
||||
|
||||
<div class="list-group">
|
||||
<a href="menu.php" class="list-group-item list-group-item-action">Manage Menu</a>
|
||||
<a href="orders.php" class="list-group-item list-group-item-action">View Orders</a>
|
||||
<a href="edit_restaurant.php" class="list-group-item list-group-item-action">Edit Restaurant Information</a>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
73
restaurant/menu.php
Normal file
73
restaurant/menu.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Check if the user is logged in as a restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// Get the restaurant ID associated with the logged-in user
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if (!$restaurant) {
|
||||
// If for some reason the user is a restaurant owner but has no restaurant, redirect them
|
||||
header('Location: ../index.php');
|
||||
exit;
|
||||
}
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
// Get restaurant details
|
||||
$stmt = $pdo->prepare("SELECT name FROM restaurants WHERE id = ?");
|
||||
$stmt->execute([$restaurant_id]);
|
||||
$restaurant_details = $stmt->fetch();
|
||||
|
||||
|
||||
// Get menu items for the restaurant
|
||||
$stmt = $pdo->prepare("SELECT * FROM menu_items WHERE restaurant_id = ? ORDER BY name");
|
||||
$stmt->execute([$restaurant_id]);
|
||||
$menu_items = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Manage Menu for <?php echo htmlspecialchars($restaurant_details['name']); ?></h2>
|
||||
<p><a href="add_menu_item.php" class="btn btn-success">Add New Menu Item</a></p>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Price</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($menu_items)): ?>
|
||||
<tr>
|
||||
<td colspan="4">No menu items found.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($menu_items as $item): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($item['name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($item['description']); ?></td>
|
||||
<td>$<?php echo htmlspecialchars(number_format($item['price'], 2)); ?></td>
|
||||
<td>
|
||||
<a href="edit_menu_item.php?id=<?php echo $item['id']; ?>" class="btn btn-primary btn-sm">Edit</a>
|
||||
<a href="delete_menu_item.php?id=<?php echo $item['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this item?');">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="index.php" class="btn btn-secondary">Back to Dashboard</a>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
124
restaurant/order_details.php
Normal file
124
restaurant/order_details.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Ensure the user is a logged-in restaurant owner
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'restaurant_owner') {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_GET['order_id'])) {
|
||||
echo "<div class='alert alert-danger'>No order ID specified.</div>";
|
||||
include 'footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$owner_id = $_SESSION['user_id'];
|
||||
$order_id = $_GET['order_id'];
|
||||
$pdo = db();
|
||||
|
||||
// Get the owner's restaurant ID
|
||||
$stmt = $pdo->prepare("SELECT id FROM restaurants WHERE user_id = ?");
|
||||
$stmt->execute([$owner_id]);
|
||||
$restaurant = $stmt->fetch();
|
||||
|
||||
if (!$restaurant) {
|
||||
echo "<div class='alert alert-danger'>You are not associated with any restaurant.</div>";
|
||||
include 'footer.php';
|
||||
exit;
|
||||
}
|
||||
$restaurant_id = $restaurant['id'];
|
||||
|
||||
// Security Check: Verify the order belongs to the restaurant owner
|
||||
$check_stmt = $pdo->prepare("
|
||||
SELECT o.id
|
||||
FROM orders o
|
||||
JOIN order_items oi ON o.id = oi.order_id
|
||||
JOIN menu_items mi ON oi.menu_item_id = mi.id
|
||||
WHERE o.id = ? AND mi.restaurant_id = ?
|
||||
LIMIT 1
|
||||
");
|
||||
$check_stmt->execute([$order_id, $restaurant_id]);
|
||||
if ($check_stmt->rowCount() == 0) {
|
||||
echo "<div class='alert alert-danger'>Access Denied: This order does not belong to your restaurant.</div>";
|
||||
include 'footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch order details
|
||||
$order_stmt = $pdo->prepare("
|
||||
SELECT o.*, u.name AS user_name, u.email AS user_email, u.address AS user_address
|
||||
FROM orders o
|
||||
JOIN users u ON o.user_id = u.id
|
||||
WHERE o.id = ?
|
||||
");
|
||||
$order_stmt->execute([$order_id]);
|
||||
$order = $order_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$order) {
|
||||
echo "<div class='alert alert-danger'>Order not found.</div>";
|
||||
include 'footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch order items
|
||||
$items_stmt = $pdo->prepare("
|
||||
SELECT oi.quantity, oi.price, mi.name AS item_name
|
||||
FROM order_items oi
|
||||
JOIN menu_items mi ON oi.menu_item_id = mi.id
|
||||
WHERE oi.order_id = ? AND mi.restaurant_id = ?
|
||||
");
|
||||
$items_stmt->execute([$order_id, $restaurant_id]);
|
||||
$items = $items_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$possible_statuses = ['Pending', 'Confirmed', 'Preparing', 'Out for Delivery', 'Delivered', 'Cancelled'];
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h2>Order Details #<?php echo htmlspecialchars($order['id']); ?></h2>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">Customer & Order Information</div>
|
||||
<div class="card-body">
|
||||
<p><strong>Customer Name:</strong> <?php echo htmlspecialchars($order['user_name']); ?></p>
|
||||
<p><strong>Customer Email:</strong> <?php echo htmlspecialchars($order['user_email']); ?></p>
|
||||
<p><strong>Delivery Address:</strong> <?php echo htmlspecialchars($order['user_address']); ?></p>
|
||||
<hr>
|
||||
<p><strong>Order Total:</strong> $<?php echo number_format($order['total_price'], 2); ?></p>
|
||||
<p><strong>Order Status:</strong> <?php echo htmlspecialchars($order['status']); ?></p>
|
||||
<p><strong>Order Date:</strong> <?php echo $order['created_at']; ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">Order Items</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Item Name</th>
|
||||
<th>Quantity</th>
|
||||
<th>Price per item</th>
|
||||
<th>Subtotal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($item['item_name']); ?></td>
|
||||
<td><?php echo $item['quantity']; ?></td>
|
||||
<td>$<?php echo number_format($item['price'], 2); ?></td>
|
||||
<td>$<?php echo number_format($item['price'] * $item['quantity'], 2); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="orders.php" class="btn btn-secondary">Back to Orders List</a>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
148
restaurant/orders.php
Normal file
148
restaurant/orders.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
include 'header.php';
|
||||
require_once '../db/config.php';
|
||||
|
||||
// Ensure the user is a logged-in restaurant owner
|
||||
if (!isset($_SESSION['restaurant_user_id'])) {
|
||||
header('Location: ../restaurant_login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$restaurant_id = $_SESSION['restaurant_id'];
|
||||
|
||||
// Fetch orders belonging to this restaurant
|
||||
$stmt = $pdo->prepare("
|
||||
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
|
||||
WHERE o.restaurant_id = ?
|
||||
ORDER BY o.created_at DESC
|
||||
");
|
||||
$stmt->execute([$restaurant_id]);
|
||||
$orders = $stmt->fetchAll();
|
||||
|
||||
$possible_statuses = ['Pending', 'Confirmed', 'Preparing', 'Out for Delivery', 'Delivered', 'Cancelled'];
|
||||
?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2>Your Restaurant's Orders</h2>
|
||||
<span class="badge badge-success" id="update-indicator" style="display: none;">Updated just now</span>
|
||||
</div>
|
||||
|
||||
<div id="orders-table-container">
|
||||
<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>Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="orders-tbody">
|
||||
<?php if (empty($orders)): ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">No orders found.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($orders as $order): ?>
|
||||
<tr data-order-id="<?php echo $order['id']; ?>">
|
||||
<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>
|
||||
<select class="form-control form-control-sm status-select">
|
||||
<?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>
|
||||
</td>
|
||||
<td>
|
||||
<a href="order_details.php?order_id=<?php echo $order['id']; ?>" class="btn btn-info btn-sm">View Details</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const ordersTbody = document.getElementById('orders-tbody');
|
||||
const updateIndicator = document.getElementById('update-indicator');
|
||||
|
||||
// --- Function to update status via API ---
|
||||
async function updateOrderStatus(orderId, newStatus) {
|
||||
try {
|
||||
const response = await fetch('update_order_status.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ order_id: orderId, status: newStatus }),
|
||||
});
|
||||
const result = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(result.error || 'Failed to update status');
|
||||
}
|
||||
console.log('Status updated:', result.message);
|
||||
showUpdateIndicator();
|
||||
} catch (error) {
|
||||
console.error('Error updating status:', error);
|
||||
alert('Error: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Attach event listener to dropdowns ---
|
||||
ordersTbody.addEventListener('change', function (e) {
|
||||
if (e.target.classList.contains('status-select')) {
|
||||
const selectedStatus = e.target.value;
|
||||
const orderId = e.target.closest('tr').dataset.orderId;
|
||||
updateOrderStatus(orderId, selectedStatus);
|
||||
}
|
||||
});
|
||||
|
||||
// --- Function to show a brief update indicator ---
|
||||
function showUpdateIndicator() {
|
||||
updateIndicator.style.display = 'inline';
|
||||
setTimeout(() => {
|
||||
updateIndicator.style.display = 'none';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// --- Function to fetch and refresh the order list ---
|
||||
async function fetchOrders() {
|
||||
try {
|
||||
const response = await fetch(window.location.href, { // Fetch the same page
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest' // To identify AJAX request on server if needed
|
||||
}
|
||||
});
|
||||
const html = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const newTbody = doc.getElementById('orders-tbody');
|
||||
if (newTbody && ordersTbody.innerHTML.trim() !== newTbody.innerHTML.trim()) {
|
||||
ordersTbody.innerHTML = newTbody.innerHTML;
|
||||
console.log('Orders refreshed');
|
||||
showUpdateIndicator();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching orders:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Polling: Refresh orders every 15 seconds ---
|
||||
setInterval(fetchOrders, 15000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
49
restaurant/update_order_status.php
Normal file
49
restaurant/update_order_status.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once '../db/config.php';
|
||||
|
||||
if (!isset($_SESSION['restaurant_user_id'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Unauthorized']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Method Not Allowed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$order_id = $data['order_id'] ?? null;
|
||||
$status = $data['status'] ?? null;
|
||||
$restaurant_id = $_SESSION['restaurant_id'];
|
||||
|
||||
if (!$order_id || !$status) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Missing order_id or status']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verify the order belongs to the restaurant
|
||||
$stmt = $pdo->prepare('SELECT id FROM orders WHERE id = ? AND restaurant_id = ?');
|
||||
$stmt->execute([$order_id, $restaurant_id]);
|
||||
$order = $stmt->fetch();
|
||||
|
||||
if (!$order) {
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'Order not found or access denied']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Update the order status
|
||||
$stmt = $pdo->prepare('UPDATE orders SET status = ? WHERE id = ?');
|
||||
$success = $stmt->execute([$status, $order_id]);
|
||||
|
||||
if ($success) {
|
||||
echo json_encode(['success' => true, 'message' => 'Order status updated successfully.']);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Failed to update order status']);
|
||||
}
|
||||
?>
|
||||
23
restaurant_login.php
Normal file
23
restaurant_login.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php include 'header.php'; ?>
|
||||
|
||||
<main>
|
||||
<div class="auth-container">
|
||||
<h1>Restaurant Owner Login</h1>
|
||||
<form action="restaurant_login_process.php" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" name="email" 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-submit">Login</button>
|
||||
</form>
|
||||
<div class="form-footer">
|
||||
<p>Don't have an account? <a href="restaurant_signup.php">Sign up</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
52
restaurant_login_process.php
Normal file
52
restaurant_login_process.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$email = $_POST['email'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
if (empty($email) || empty($password)) {
|
||||
die('Please fill all required fields.');
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
die('Invalid email format.');
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
$sql = "SELECT * FROM users WHERE email = ?";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$email]);
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
if ($user['role'] !== 'restaurant_owner') {
|
||||
die('You are not authorized to access this page.');
|
||||
}
|
||||
|
||||
// Fetch the restaurant ID
|
||||
$sql = "SELECT id FROM restaurants WHERE user_id = ?";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$user['id']]);
|
||||
$restaurant = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['user_name'] = $user['name'];
|
||||
$_SESSION['user_role'] = $user['role'];
|
||||
if ($restaurant) {
|
||||
$_SESSION['restaurant_id'] = $restaurant['id'];
|
||||
}
|
||||
|
||||
header("Location: restaurant/index.php");
|
||||
exit;
|
||||
} else {
|
||||
die('Invalid email or password.');
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
die("Could not connect to the database: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
42
restaurant_signup.php
Normal file
42
restaurant_signup.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php include 'header.php'; ?>
|
||||
|
||||
<main>
|
||||
<div class="auth-container">
|
||||
<h1>Create a Restaurant Account</h1>
|
||||
<p>Sign up to list your restaurant on our platform.</p>
|
||||
<form action="restaurant_signup_process.php" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Your Name</label>
|
||||
<input type="text" id="name" name="name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Restaurant Details</h3>
|
||||
<div class="form-group">
|
||||
<label for="restaurant_name">Restaurant Name</label>
|
||||
<input type="text" id="restaurant_name" name="restaurant_name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="restaurant_address">Restaurant Address</label>
|
||||
<input type="text" id="restaurant_address" name="restaurant_address" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="restaurant_phone">Restaurant Phone</label>
|
||||
<input type="text" id="restaurant_phone" name="restaurant_phone" required>
|
||||
</div>
|
||||
<button type="submit" class="btn-submit">Sign Up</button>
|
||||
</form>
|
||||
<div class="form-footer">
|
||||
<p>Already have an account? <a href="restaurant_login.php">Log in</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
62
restaurant_signup_process.php
Normal file
62
restaurant_signup_process.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
// User details
|
||||
$name = $_POST['name'];
|
||||
$email = $_POST['email'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
// Restaurant details
|
||||
$restaurant_name = $_POST['restaurant_name'];
|
||||
$restaurant_address = $_POST['restaurant_address'];
|
||||
$restaurant_phone = $_POST['restaurant_phone'];
|
||||
|
||||
if (empty($name) || empty($email) || empty($password) || empty($restaurant_name) || empty($restaurant_address) || empty($restaurant_phone)) {
|
||||
die('Please fill all required fields.');
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
die('Invalid email format.');
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
// Check if email already exists
|
||||
$sql = "SELECT id FROM users WHERE email = ?";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$email]);
|
||||
if ($stmt->fetch()) {
|
||||
die('Email already exists.');
|
||||
}
|
||||
|
||||
// Create the user with 'restaurant_owner' role
|
||||
$password_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
$sql = "INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, 'restaurant_owner')";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$name, $email, $password_hash]);
|
||||
$user_id = $pdo->lastInsertId();
|
||||
|
||||
// Create the restaurant
|
||||
$sql = "INSERT INTO restaurants (name, address, phone_number, user_id) VALUES (?, ?, ?, ?)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$restaurant_name, $restaurant_address, $restaurant_phone, $user_id]);
|
||||
$restaurant_id = $pdo->lastInsertId();
|
||||
|
||||
// Log the user in
|
||||
$_SESSION['user_id'] = $user_id;
|
||||
$_SESSION['user_name'] = $name;
|
||||
$_SESSION['user_role'] = 'restaurant_owner';
|
||||
$_SESSION['restaurant_id'] = $restaurant_id;
|
||||
|
||||
// Redirect to the restaurant dashboard
|
||||
header("Location: restaurant/index.php");
|
||||
exit;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
die("Could not connect to the database: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
Loading…
x
Reference in New Issue
Block a user