diff --git a/admin/footer.php b/admin/footer.php new file mode 100644 index 00000000..9943ff0f --- /dev/null +++ b/admin/footer.php @@ -0,0 +1,3 @@ + + + diff --git a/admin/header.php b/admin/header.php new file mode 100644 index 00000000..6679a651 --- /dev/null +++ b/admin/header.php @@ -0,0 +1,29 @@ + + + + + + + Admin Panel + + + + +
diff --git a/admin/index.php b/admin/index.php new file mode 100644 index 00000000..a65f150d --- /dev/null +++ b/admin/index.php @@ -0,0 +1,45 @@ +query("SELECT o.id, o.user_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(PDO::FETCH_ASSOC); +?> + +

Order Management

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Order IDCustomerTotal PriceStatusOrder DateActions
No orders found.
$ + View Details +
+ + diff --git a/admin/login.php b/admin/login.php new file mode 100644 index 00000000..019bd883 --- /dev/null +++ b/admin/login.php @@ -0,0 +1,47 @@ + + + + + + + Admin Login + + + +
+
+
+
+
+ Admin Login +
+
+ +
+ +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + diff --git a/admin/login_process.php b/admin/login_process.php new file mode 100644 index 00000000..098c0cba --- /dev/null +++ b/admin/login_process.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/admin/logout.php b/admin/logout.php new file mode 100644 index 00000000..95db42cf --- /dev/null +++ b/admin/logout.php @@ -0,0 +1,6 @@ +No order ID specified.
"; + require_once 'footer.php'; + exit; +} + +$order_id = $_GET['id']; +$db = db(); + +// Handle status update +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['status'])) { + $status = $_POST['status']; + $update_stmt = $db->prepare("UPDATE orders SET status = :status WHERE id = :order_id"); + $update_stmt->bindParam(':status', $status); + $update_stmt->bindParam(':order_id', $order_id); + $update_stmt->execute(); +} + +// Fetch order details +$order_stmt = $db->prepare("SELECT o.*, u.name AS user_name, u.email AS user_email FROM orders o JOIN users u ON o.user_id = u.id WHERE o.id = :order_id"); +$order_stmt->bindParam(':order_id', $order_id); +$order_stmt->execute(); +$order = $order_stmt->fetch(PDO::FETCH_ASSOC); + +if (!$order) { + echo "
Order not found.
"; + require_once 'footer.php'; + exit; +} + +// Fetch order items +$items_stmt = $db->prepare("SELECT oi.*, p.name AS product_name FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = :order_id"); +$items_stmt->bindParam(':order_id', $order_id); +$items_stmt->execute(); +$items = $items_stmt->fetchAll(PDO::FETCH_ASSOC); +?> + +

Order Details #

+ +
+
Customer & Order Info
+
+

Customer:

+

Email:

+

Address:

+

Total Price: $

+

Order Date:

+

Status:

+
+
+ +
+
Order Items
+
+ + + + + + + + + + + + + + + + + +
ProductQuantityPrice
$
+
+
+ +
+
Update Status
+
+
+
+ + +
+
+
+
+ +Back to Orders + + diff --git a/cart.php b/cart.php index 85f951db..3874cb70 100644 --- a/cart.php +++ b/cart.php @@ -1,80 +1,67 @@ prepare("SELECT * FROM menu_items WHERE id IN ($placeholders)"); - $stmt->execute($menu_item_ids); - $db_items = $stmt->fetchAll(PDO::FETCH_ASSOC); - - foreach ($db_items as $item) { - $quantity = $_SESSION['cart'][$item['id']]; - $item_total = $item['price'] * $quantity; - $total_price += $item_total; - $cart_items[] = [ - 'id' => $item['id'], - 'name' => $item['name'], - 'price' => $item['price'], - 'quantity' => $quantity, - 'total' => $item_total - ]; - } +// Fetch cart items +if ($user_id) { + $stmt = $pdoconnection->prepare("SELECT c.id, mi.name, mi.price, c.quantity, r.name as restaurant_name FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id JOIN restaurants r ON mi.restaurant_id = r.id WHERE c.user_id = :user_id"); + $stmt->bindParam(':user_id', $user_id); +} else { + $stmt = $pdoconnection->prepare("SELECT c.id, mi.name, mi.price, c.quantity, r.name as restaurant_name FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id JOIN restaurants r ON mi.restaurant_id = r.id WHERE c.session_id = :session_id"); + $stmt->bindParam(':session_id', $session_id); } + +$stmt->execute(); +$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); + +$totalPrice = 0; + +include 'header.php'; ?> -
-
-

Your Cart

- -

Your cart is empty.

- - - - - - - - - - - - - - - - - - - - - - -
ItemPriceQuantityTotalAction
$ -
- - - - -
-
$ - Remove -
-
-

Total: $

-
- - -
-
+
+

Your Shopping Cart

- \ No newline at end of file + 0): ?> + + + + + + + + + + + + + + + + + + + + +
ItemPriceQuantityTotal
$$
+ +
+

Subtotal: $

+ Proceed to Checkout +
+ +
+

Your cart is empty.

+ Continue Shopping +
+ +
+ + diff --git a/cart_actions.php b/cart_actions.php index e9e64951..b8fc9082 100644 --- a/cart_actions.php +++ b/cart_actions.php @@ -2,14 +2,8 @@ session_start(); require_once 'db/config.php'; -// Check if user is logged in, if not, redirect to login page -if (!isset($_SESSION['user_id'])) { - // For now, we'll use a hardcoded user_id for simplicity. - // In a real application, you would redirect to a login page. - $_SESSION['user_id'] = 1; // Hardcoded user_id for demonstration -} - -$user_id = $_SESSION['user_id']; +$user_id = $_SESSION['user_id'] ?? null; +$session_id = session_id(); $action = $_POST['action'] ?? ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { @@ -22,8 +16,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $pdo = db(); // Check if the item is already in the cart - $stmt = $pdo->prepare("SELECT * FROM cart WHERE user_id = ? AND menu_item_id = ?"); - $stmt->execute([$user_id, $menu_item_id]); + if ($user_id) { + $stmt = $pdo->prepare("SELECT * FROM cart WHERE user_id = ? AND menu_item_id = ?"); + $stmt->execute([$user_id, $menu_item_id]); + } else { + $stmt = $pdo->prepare("SELECT * FROM cart WHERE session_id = ? AND menu_item_id = ?"); + $stmt->execute([$session_id, $menu_item_id]); + } $existing_item = $stmt->fetch(); if ($existing_item) { @@ -33,8 +32,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $update_stmt->execute([$new_quantity, $existing_item['id']]); } else { // If item does not exist, insert it - $insert_stmt = $pdo->prepare("INSERT INTO cart (user_id, menu_item_id, quantity) VALUES (?, ?, ?)"); - $insert_stmt->execute([$user_id, $menu_item_id, $quantity]); + if ($user_id) { + $insert_stmt = $pdo->prepare("INSERT INTO cart (user_id, menu_item_id, quantity) VALUES (?, ?, ?)"); + $insert_stmt->execute([$user_id, $menu_item_id, $quantity]); + } else { + $insert_stmt = $pdo->prepare("INSERT INTO cart (session_id, menu_item_id, quantity) VALUES (?, ?, ?)"); + $insert_stmt->execute([$session_id, $menu_item_id, $quantity]); + } } echo json_encode(['success' => true, 'message' => 'Item added to cart.']); diff --git a/checkout.php b/checkout.php index 07c3602b..1b2ab7a5 100644 --- a/checkout.php +++ b/checkout.php @@ -2,99 +2,76 @@ session_start(); require_once 'db/config.php'; -// If user is not logged in, redirect to login page +// Redirect to login if user is not logged in if (!isset($_SESSION['user_id'])) { - header('Location: login.php'); - exit; + header("Location: login.php"); + exit(); } -// If cart is empty, redirect to cart page -if (empty($_SESSION['cart'])) { - header('Location: cart.php'); - exit; +$userId = $_SESSION['user_id']; +$pdoconnection = db(); + +// Fetch cart items +$stmt = $pdoconnection->prepare("SELECT c.id, mi.name, mi.price, c.quantity, r.name as restaurant_name, r.id as restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id JOIN restaurants r ON mi.restaurant_id = r.id WHERE c.user_id = :user_id"); +$stmt->bindParam(':user_id', $userId); +$stmt->execute(); +$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if (empty($cartItems)) { + header("Location: cart.php"); + exit(); } -$cart_items = []; -$total_price = 0; -$restaurant_id = $_SESSION['cart_restaurant']; - -$menu_item_ids = array_keys($_SESSION['cart']); -$placeholders = implode(',', array_fill(0, count($menu_item_ids), '?')); - -$stmt = db()->prepare("SELECT * FROM menu_items WHERE id IN ($placeholders)"); -$stmt->execute($menu_item_ids); -$db_items = $stmt->fetchAll(PDO::FETCH_ASSOC); - -foreach ($db_items as $item) { - $quantity = $_SESSION['cart'][$item['id']]; - $item_total = $item['price'] * $quantity; - $total_price += $item_total; - $cart_items[] = [ - 'id' => $item['id'], - 'name' => $item['name'], - 'price' => $item['price'], - 'quantity' => $quantity, - 'total' => $item_total - ]; -} - -if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $user_id = $_SESSION['user_id']; - - // Insert into orders table - $stmt = db()->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status) VALUES (?, ?, ?, ?)"); - $stmt->execute([$user_id, $restaurant_id, $total_price, 'pending']); - $order_id = db()->lastInsertId(); - - // Insert into order_items table - $stmt = db()->prepare("INSERT INTO order_items (order_id, menu_item_id, quantity, price) VALUES (?, ?, ?, ?)"); - foreach ($cart_items as $item) { - $stmt->execute([$order_id, $item['id'], $item['quantity'], $item['price']]); - } - - // Clear the cart - $_SESSION['cart'] = []; - $_SESSION['cart_restaurant'] = null; - - // Redirect to a confirmation page - header('Location: order_confirmation.php?id=' . $order_id); - exit; +$totalPrice = 0; +$restaurantId = $cartItems[0]['restaurant_id']; +$restaurantName = $cartItems[0]['restaurant_name']; +foreach ($cartItems as $item) { + $totalPrice += $item['price'] * $item['quantity']; } include 'header.php'; ?> -
-
-

Checkout

-
-

Order Summary

- - - - - - - - - - - - - - - - - -
ItemQuantityTotal
$
-
-

Total: $

-
-
- +
+

Checkout

+
+
+

Delivery Information

+ +
+ + +
+
+ + +
+
+ + +
+ + +
+
+

Order Summary

+
+
    + +
  • + (x) + $ +
  • + +
  • + Total + $ +
  • +
+
-
+ - + \ No newline at end of file diff --git a/footer.php b/footer.php index 7fb4b2d7..1cf7e3fe 100644 --- a/footer.php +++ b/footer.php @@ -1,6 +1,6 @@ diff --git a/header.php b/header.php index a83297d4..a5b2ccd1 100644 --- a/header.php +++ b/header.php @@ -21,7 +21,24 @@ session_start();
prepare('SELECT SUM(quantity) as item_count FROM cart WHERE user_id = ?'); + $stmt->execute([$_SESSION['user_id']]); + $result = $stmt->fetch(); + if ($result && $result['item_count'] > 0) { + $cart_item_count = $result['item_count']; + } + } else { + $stmt = $db->prepare('SELECT SUM(quantity) as item_count FROM cart WHERE session_id = ?'); + $stmt->execute([session_id()]); + $result = $stmt->fetch(); + if ($result && $result['item_count'] > 0) { + $cart_item_count = $result['item_count']; + } + } ?> @@ -29,6 +46,7 @@ session_start(); Welcome, + My Profile Logout Login diff --git a/login_process.php b/login_process.php index c3874f8c..69dc54f6 100644 --- a/login_process.php +++ b/login_process.php @@ -23,7 +23,15 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { - $_SESSION['user_id'] = $user['id']; + $user_id = $user['id']; + $session_id = session_id(); + + // Merge guest cart with user cart + $merge_sql = "UPDATE cart SET user_id = ?, session_id = NULL WHERE session_id = ?"; + $merge_stmt = $pdo->prepare($merge_sql); + $merge_stmt->execute([$user_id, $session_id]); + + $_SESSION['user_id'] = $user_id; $_SESSION['user_name'] = $user['name']; header("Location: index.php"); exit; diff --git a/menu.php b/menu.php index 7df8d62a..f88a2cba 100644 --- a/menu.php +++ b/menu.php @@ -11,8 +11,14 @@ if (!$restaurant_id) { $pdo = db(); -// Fetch restaurant details -$restaurant_stmt = $pdo->prepare("SELECT * FROM restaurants WHERE id = ?"); +// Fetch restaurant details along with average rating +$restaurant_stmt = $pdo->prepare(" + SELECT r.*, AVG(rt.rating) as rating, COUNT(rt.id) as rating_count + FROM restaurants r + LEFT JOIN ratings rt ON r.id = rt.restaurant_id + WHERE r.id = ? + GROUP BY r.id +"); $restaurant_stmt->execute([$restaurant_id]); $restaurant = $restaurant_stmt->fetch(PDO::FETCH_ASSOC); diff --git a/migrations/20251015_create_ratings_table.sql b/migrations/20251015_create_ratings_table.sql new file mode 100644 index 00000000..54268171 --- /dev/null +++ b/migrations/20251015_create_ratings_table.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS `ratings` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `order_id` INT NOT NULL, + `restaurant_id` INT NOT NULL, + `user_id` INT NOT NULL, + `rating` INT NOT NULL, + `comment` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`), + FOREIGN KEY (`restaurant_id`) REFERENCES `restaurants`(`id`), + FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) +); diff --git a/migrations/20251015_create_users_table.sql b/migrations/20251015_create_users_table.sql new file mode 100644 index 00000000..fcb4fd90 --- /dev/null +++ b/migrations/20251015_create_users_table.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE, + `password` VARCHAR(255) NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/migrations/20251015_update_cart_table.sql b/migrations/20251015_update_cart_table.sql new file mode 100644 index 00000000..93e9f825 --- /dev/null +++ b/migrations/20251015_update_cart_table.sql @@ -0,0 +1,2 @@ +ALTER TABLE `cart` ADD `session_id` VARCHAR(255) NULL AFTER `user_id`; +ALTER TABLE `cart` MODIFY `user_id` INT NULL; diff --git a/order_confirmation.php b/order_confirmation.php index c1f9bd74..172ec498 100644 --- a/order_confirmation.php +++ b/order_confirmation.php @@ -1,25 +1,32 @@ -
-
-

Thank You for Your Order!

-

Your order has been placed successfully.

-

Your Order ID is:

- Continue Shopping +
+
+
+

Thank You for Your Order!

+

Your order has been placed successfully.

+

Your Order ID is:

+

We have received your order and will begin processing it shortly.

+ Continue Shopping +
-
+
- \ No newline at end of file + diff --git a/order_process.php b/order_process.php new file mode 100644 index 00000000..4467ca97 --- /dev/null +++ b/order_process.php @@ -0,0 +1,56 @@ +prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status) VALUES (:user_id, :restaurant_id, :total_price, 'pending')"); + $stmt->bindParam(':user_id', $userId); + $stmt->bindParam(':restaurant_id', $_POST['restaurant_id']); + $stmt->bindParam(':total_price', $_POST['total_price']); + $stmt->execute(); + $orderId = $pdoconnection->lastInsertId(); + + // Get cart items + $stmt = $pdoconnection->prepare("SELECT * FROM cart WHERE user_id = :user_id"); + $stmt->bindParam(':user_id', $userId); + $stmt->execute(); + $cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // Move cart items to order_items + $stmt = $pdoconnection->prepare("INSERT INTO order_items (order_id, menu_item_id, quantity, price) VALUES (:order_id, :menu_item_id, :quantity, :price)"); + foreach ($cartItems as $item) { + // Get menu item price + $priceStmt = $pdoconnection->prepare("SELECT price FROM menu_items WHERE id = :menu_item_id"); + $priceStmt->bindParam(':menu_item_id', $item['menu_item_id']); + $priceStmt->execute(); + $menuItem = $priceStmt->fetch(PDO::FETCH_ASSOC); + + $stmt->bindParam(':order_id', $orderId); + $stmt->bindParam(':menu_item_id', $item['menu_item_id']); + $stmt->bindParam(':quantity', $item['quantity']); + $stmt->bindParam(':price', $menuItem['price']); + $stmt->execute(); + } + + // Clear the cart + $stmt = $pdoconnection->prepare("DELETE FROM cart WHERE user_id = :user_id"); + $stmt->bindParam(':user_id', $userId); + $stmt->execute(); + + // Redirect to order confirmation + header("Location: order_confirmation.php?id=" . $orderId); + exit(); +} else { + header("Location: checkout.php"); + exit(); +} +?> \ No newline at end of file diff --git a/profile.php b/profile.php new file mode 100644 index 00000000..b615f8a8 --- /dev/null +++ b/profile.php @@ -0,0 +1,106 @@ +prepare(" + SELECT o.*, r.id AS restaurant_id, r.name AS restaurant_name + FROM orders o + JOIN order_items oi ON o.id = oi.order_id + JOIN menu_items mi ON oi.menu_item_id = mi.id + JOIN restaurants r ON mi.restaurant_id = r.id + WHERE o.user_id = ? + GROUP BY o.id + ORDER BY o.order_date DESC +"); +$stmt->execute([$user_id]); +$orders = $stmt->fetchAll(PDO::FETCH_ASSOC); + +include 'header.php'; +?> + +
+

My Profile

+

My Orders

+ ' . $_SESSION['rating_success'] . '
'; + unset($_SESSION['rating_success']); + } + if (isset($_SESSION['rating_error'])) { + echo '
' . $_SESSION['rating_error'] . '
'; + unset($_SESSION['rating_error']); + } + ?> + 0): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
Order IDOrder DateRestaurantTotal AmountStatusAction
$ + View Details + + + +
+ +

You have no past orders.

+ + + + diff --git a/rate.php b/rate.php index 6dccc387..a3047148 100644 --- a/rate.php +++ b/rate.php @@ -1,37 +1,48 @@ prepare("SELECT rating, rating_count FROM restaurants WHERE id = ?"); - $stmt->execute([$restaurant_id]); - $restaurant = $stmt->fetch(PDO::FETCH_ASSOC); - - if ($restaurant) { - $current_total_rating = $restaurant['rating'] * $restaurant['rating_count']; - $new_total_rating = $current_total_rating + $new_rating; - $new_rating_count = $restaurant['rating_count'] + 1; - $new_average_rating = $new_total_rating / $new_rating_count; - - // Update restaurant with new rating - $update_stmt = $pdo->prepare("UPDATE restaurants SET rating = ?, rating_count = ? WHERE id = ?"); - $update_stmt->execute([$new_average_rating, $new_rating_count, $restaurant_id]); - } - } catch (PDOException $e) { - // Log error, but don't show to user - error_log("Rating update failed: " . $e->getMessage()); - } - } +if (!isset($_SESSION['user_id'])) { + header("Location: login.php"); + exit(); } -// Redirect back to the menu page -header('Location: menu.php?id=' . $restaurant_id); -exit; +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $user_id = $_SESSION['user_id']; + $order_id = $_POST['order_id']; + $restaurant_id = $_POST['restaurant_id']; + $rating = $_POST['rating']; + $comment = $_POST['comment']; + + // Validation + if (empty($order_id) || empty($restaurant_id) || empty($rating) || $rating < 1 || $rating > 5) { + // Handle error - redirect back to profile with an error message + $_SESSION['rating_error'] = "Invalid data provided."; + header("Location: profile.php"); + exit(); + } + + // Check if the user has already rated this order + $stmt = $db()->prepare("SELECT id FROM ratings WHERE user_id = ? AND order_id = ?"); + $stmt->execute([$user_id, $order_id]); + if ($stmt->fetch()) { + $_SESSION['rating_error'] = "You have already rated this order."; + header("Location: profile.php"); + exit(); + } + + // Insert the rating + $stmt = $db()->prepare("INSERT INTO ratings (user_id, order_id, restaurant_id, rating, comment) VALUES (?, ?, ?, ?, ?)"); + if ($stmt->execute([$user_id, $order_id, $restaurant_id, $rating, $comment])) { + $_SESSION['rating_success'] = "Thank you for your feedback!"; + } else { + $_SESSION['rating_error'] = "Something went wrong. Please try again."; + } + + header("Location: profile.php"); + exit(); +} else { + header("Location: profile.php"); + exit(); +} ?> \ No newline at end of file