diff --git a/api/get_order_status.php b/api/get_order_status.php index 3f64edae..46d9d51f 100644 --- a/api/get_order_status.php +++ b/api/get_order_status.php @@ -3,35 +3,43 @@ header('Content-Type: application/json'); session_start(); require_once __DIR__ . '/../db/config.php'; -// Check if user is logged in -if (!isset($_SESSION['user_id'])) { - echo json_encode(['error' => 'User not authenticated']); - exit; -} +$order_id = $_GET['order_id'] ?? null; +$token = $_GET['token'] ?? null; +$user_id = $_SESSION['user_id'] ?? null; -// Check if order_id is provided -if (!isset($_GET['order_id'])) { +if (!$order_id) { echo json_encode(['error' => 'Order ID not specified']); exit; } -$order_id = $_GET['order_id']; -$user_id = $_SESSION['user_id']; +$status = null; try { $pdo = db(); + + if ($user_id) { + $stmt = $pdo->prepare("SELECT status FROM orders WHERE id = ? AND user_id = ?"); + $stmt->execute([$order_id, $user_id]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + if ($result) { + $status = $result['status']; + } + } elseif ($token) { + $stmt = $pdo->prepare("SELECT status FROM orders WHERE id = ? AND guest_token = ?"); + $stmt->execute([$order_id, $token]); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + if ($result) { + $status = $result['status']; + } + } - // Fetch the order status, ensuring the order belongs to the logged-in user - $stmt = $pdo->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' => ucwords($order['status'])]); + if ($status) { + echo json_encode(['status' => ucwords($status)]); } else { echo json_encode(['error' => 'Order not found or permission denied']); } + } catch (PDOException $e) { - echo json_encode(['error' => 'Database error']); + http_response_code(500); + echo json_encode(['error' => 'Database connection error']); } -?> \ No newline at end of file diff --git a/assets/css/main.css b/assets/css/main.css index 4d065668..41be8532 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -264,17 +264,17 @@ footer { /* Restaurant Menu Page */ .restaurant-hero-menu { position: relative; - height: 300px; + height: 350px; background-size: cover; background-position: center; display: flex; flex-direction: column; justify-content: flex-end; - padding: 2rem; + padding: 3rem; color: var(--white); - border-radius: var(--border-radius); + border-radius: 0 0 var(--border-radius) var(--border-radius); overflow: hidden; - margin-bottom: 2rem; + margin-bottom: 3rem; } .restaurant-hero-menu::after { @@ -284,7 +284,7 @@ footer { left: 0; width: 100%; height: 100%; - background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0) 100%); + background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.1) 100%); } .restaurant-hero-menu-content { @@ -293,23 +293,23 @@ footer { } .restaurant-hero-menu h1 { - font-size: 2.5rem; + font-size: 3rem; font-weight: 700; margin: 0 0 0.5rem; - text-shadow: 0 2px 4px rgba(0,0,0,0.6); + text-shadow: 0 2px 8px rgba(0,0,0,0.7); } .restaurant-hero-menu p { - font-size: 1rem; + font-size: 1.1rem; margin: 0.25rem 0; - text-shadow: 0 1px 3px rgba(0,0,0,0.5); + text-shadow: 0 1px 5px rgba(0,0,0,0.6); } /* Menu Grid */ .menu-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 2rem; + grid-template-columns: 1fr; + gap: 1.5rem; } .menu-item-card { @@ -319,7 +319,8 @@ footer { overflow: hidden; transition: all 0.3s ease-in-out; display: flex; - flex-direction: column; + justify-content: space-between; + padding: 1.5rem; } .menu-item-card:hover { @@ -327,21 +328,23 @@ footer { box-shadow: 0 8px 20px rgba(0,0,0,0.12); } -.menu-item-card img { - width: 100%; - height: 180px; +.menu-item-image { + width: 120px; + height: 120px; object-fit: cover; + border-radius: 12px; + margin-left: 1.5rem; } .menu-item-card-content { - padding: 1.5rem; + padding: 0; display: flex; flex-direction: column; flex-grow: 1; } .menu-item-card-content h3 { - font-size: 1.15rem; + font-size: 1.2rem; font-weight: 700; margin: 0 0 0.5rem; } @@ -357,9 +360,50 @@ footer { font-size: 1.1rem; font-weight: 700; color: var(--text-color); - align-self: flex-end; } +/* Reviews Section */ +.reviews-section { + background-color: var(--white); + padding: 2rem; + border-radius: var(--border-radius); + box-shadow: var(--shadow-soft); + position: sticky; + top: 120px; /* Adjust based on header height */ +} + +.review-card { + border-bottom: 1px solid var(--light-gray); + padding: 1.5rem 0; +} + +.review-card:last-child { + border-bottom: none; + padding-bottom: 0; +} + +.review-card:first-child { + padding-top: 0; +} + +.review-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; +} + +.review-header strong { + font-size: 1rem; +} + +.review-text { + font-style: italic; + color: var(--dark-gray); + margin-bottom: 0.5rem; +} + + /* Rating Section on Menu Page */ .rating-form-container { background-color: var(--white); @@ -1029,4 +1073,476 @@ footer { .col-md-9 { width: 100%; padding: 0; -} \ No newline at end of file +} + +/* Categories Section */ +.categories-section { + margin-bottom: 3rem; +} + +.category-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 1.5rem; +} + +.category-card { + position: relative; + border-radius: var(--border-radius); + overflow: hidden; + height: 150px; + display: flex; + align-items: flex-end; + justify-content: center; + text-decoration: none; + color: var(--white); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.category-card:hover { + transform: translateY(-5px); + box-shadow: 0 10px 20px rgba(0,0,0,0.2); +} + +.category-card img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + z-index: 1; + transition: transform 0.3s ease; +} + +.category-card:hover img { + transform: scale(1.05); +} + +.category-card-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 60%); + z-index: 2; +} + +.category-card h3 { + position: relative; + z-index: 3; + margin: 0; + padding: 1rem; + font-size: 1.2rem; + font-weight: 700; + text-align: center; + text-shadow: 0 2px 4px rgba(0,0,0,0.5); +} + +/* New Checkout Styles */ +.checkout-container { + display: flex; + min-height: 100vh; + background-color: var(--white); +} + +.checkout-main { + flex-grow: 1; + padding: 2rem 4rem; + display: flex; + flex-direction: column; +} + +.checkout-header { + margin-bottom: 3rem; +} + +.checkout-logo { + display: flex; + align-items: center; + gap: 0.75rem; + font-size: 1.5rem; + font-weight: 700; + color: var(--text-color); +} + +.step-title { + font-size: 1.75rem; + margin-bottom: 2rem; +} + +#delivery-form .form-group { + margin-bottom: 1.5rem; +} + +#delivery-form .form-control { + padding: 1rem; + font-size: 1rem; + border-radius: 8px; + border: 1px solid var(--medium-gray); +} + +.btn-primary { + width: 100%; + padding: 1rem; + font-size: 1.1rem; + font-weight: 600; + border-radius: 8px; + background-color: var(--coral); + color: white; + border: none; + cursor: pointer; + transition: background-color 0.3s; +} + +.btn-primary:hover { + background-color: #ff4f4f; +} + +.payment-methods { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.5rem; + margin-bottom: 2rem; +} + +.payment-method-card { + border: 1px solid var(--medium-gray); + border-radius: 12px; + cursor: pointer; + transition: border-color 0.3s, box-shadow 0.3s; +} + +.payment-method-card:has(input:checked) { + border-color: var(--coral); + box-shadow: 0 0 0 2px var(--coral); +} + +.payment-method-card label { + display: flex; + align-items: center; + gap: 1rem; + padding: 1.5rem; + font-size: 1.1rem; + font-weight: 600; +} + +.payment-method-card input[type="radio"] { + display: none; +} + +.payment-method-card svg { + width: 32px; + height: 32px; +} + +#paypal-button-container { + margin-top: 1rem; +} + +.btn-secondary { + width: 100%; + padding: 1rem; + font-size: 1.1rem; + font-weight: 600; + border-radius: 8px; + background-color: transparent; + color: var(--dark-gray); + border: 1px solid var(--medium-gray); + cursor: pointer; + margin-top: 1rem; + transition: background-color 0.3s, border-color 0.3s; +} + +.btn-secondary:hover { + background-color: var(--light-gray); + border-color: var(--dark-gray); +} + +.checkout-summary { + width: 450px; + background-color: var(--off-white); + padding: 2rem; + border-left: 1px solid var(--light-gray); + display: flex; + flex-direction: column; +} + +.checkout-summary h4 { + font-size: 1.5rem; + margin-bottom: 2rem; +} + +.summary-items { + flex-grow: 1; +} + +.summary-item { + display: flex; + justify-content: space-between; + margin-bottom: 1rem; + font-size: 1rem; +} + +.item-name { + color: var(--dark-gray); +} + +.item-price { + font-weight: 600; +} + +.summary-total { + border-top: 1px solid var(--medium-gray); + padding-top: 1.5rem; +} + +.summary-line { + display: flex; + justify-content: space-between; + margin-bottom: 0.75rem; + font-size: 1rem; +} + +.summary-line.discount { + color: #28a745; +} + +.summary-line.total { + font-size: 1.25rem; + font-weight: 700; + margin-top: 1rem; +} + +/* Order Confirmation Page Refined */ +.card.shadow-sm { + border: none; + border-radius: var(--border-radius); + box-shadow: var(--shadow-soft); +} + +.card-header.bg-success { + background-color: var(--coral) !important; + border-bottom: none; + border-radius: var(--border-radius) var(--border-radius) 0 0; +} + +.card-header h2 { + font-size: 1.75rem; + color: var(--white); +} + +.card-body .lead { + font-size: 1.2rem; + font-weight: 500; + color: var(--dark-gray); +} + +.card-body h5 { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 1rem; + color: var(--text-color); + border-bottom: 2px solid var(--light-gray); + padding-bottom: 0.5rem; +} + +.badge.bg-warning { + font-size: 0.9rem; + padding: 0.5em 0.75em; + background-color: var(--turquoise) !important; + color: var(--text-color) !important; +} + +.list-group-item { + border-color: var(--light-gray); +} + +.list-group-item span { + font-weight: 600; +} + +.list-group-item.fw-bold { + font-size: 1.1rem; +} + +.order-confirmation-actions .btn { + margin: 0 0.5rem; + padding: 0.8rem 1.5rem; + font-weight: 600; + text-transform: uppercase; + font-size: 0.9rem; + border-radius: 50px; + transition: all 0.3s ease; +} + +.order-confirmation-actions .btn-primary { + background-color: var(--coral); + border-color: var(--coral); +} + +.order-confirmation-actions .btn-primary:hover { + background-color: #ff4f4f; + border-color: #ff4f4f; + transform: translateY(-2px); +} + +.order-confirmation-actions .btn-secondary { + background-color: var(--off-white); + border-color: var(--medium-gray); + color: var(--dark-gray); +} + +.order-confirmation-actions .btn-secondary:hover { + background-color: var(--light-gray); + border-color: var(--dark-gray); + transform: translateY(-2px); +} + +/* Order Status Page */ +.order-status-container { + max-width: 800px; + margin: 2rem auto; + padding: 2rem; + background-color: var(--white); + border-radius: var(--border-radius); + box-shadow: var(--shadow-soft); +} + +.order-status-header { + text-align: center; + margin-bottom: 2.5rem; + border-bottom: 1px solid var(--light-gray); + padding-bottom: 1.5rem; +} + +.order-status-header h1 { + font-size: 2.2rem; + margin-bottom: 0.5rem; +} + +.order-status-header p { + font-size: 1.1rem; + color: var(--dark-gray); +} + +#order-status-timeline { + position: relative; + padding: 1rem 0; +} + +.timeline-item { + display: flex; + position: relative; + padding-left: 60px; /* Space for icon and line */ + padding-bottom: 3rem; +} + +.timeline-item:last-child { + padding-bottom: 0; +} + +.timeline-item::before { + content: ''; + position: absolute; + left: 24px; /* Center the line */ + top: 50px; + width: 2px; + height: calc(100% - 50px); + background-color: var(--light-gray); + transition: background-color 0.5s ease; +} + +.timeline-item:last-child::before { + display: none; +} + +.timeline-icon { + position: absolute; + left: 0; + top: 0; + width: 50px; + height: 50px; + border-radius: 50%; + background-color: var(--light-gray); + color: var(--medium-gray); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + z-index: 1; + border: 4px solid var(--off-white); + transition: all 0.5s ease; +} + +.timeline-content { + padding-top: 10px; +} + +.timeline-content h5 { + font-size: 1.2rem; + font-weight: 700; + margin-bottom: 0.25rem; + transition: color 0.5s ease; + border-bottom: none; + padding-bottom: 0; +} + +.timeline-content p { + font-size: 0.95rem; + color: var(--dark-gray); + margin: 0; +} + +/* --- Timeline States --- */ + +/* Default (Not yet active) */ +.timeline-item:not(.timeline-complete):not(.timeline-active) .timeline-icon { + background-color: var(--light-gray); + color: var(--medium-gray); +} + +/* Active State */ +.timeline-active .timeline-icon { + background-color: var(--turquoise); + color: var(--white); + transform: scale(1.1); + box-shadow: 0 0 15px rgba(64, 224, 208, 0.7); +} + +.timeline-active h5 { + color: var(--turquoise); +} + +/* Complete State */ +.timeline-complete::before { + background-color: var(--coral); +} + +.timeline-complete .timeline-icon { + background-color: var(--coral); + color: var(--white); +} + +/* Cancelled State */ +.timeline-cancelled .timeline-icon { + background-color: var(--dark-gray); + color: var(--white); +} + +.timeline-cancelled h5 { + color: var(--dark-gray); + text-decoration: line-through; +} + +.order-status-footer { + text-align: center; + margin-top: 2.5rem; + padding-top: 1.5rem; + border-top: 1px solid var(--light-gray); +} + +.order-status-footer p { + margin-bottom: 1rem; +} diff --git a/checkout.php b/checkout.php index ec376752..d975f095 100644 --- a/checkout.php +++ b/checkout.php @@ -3,16 +3,26 @@ session_start(); require_once 'db/config.php'; require_once 'includes/api_keys.php'; -if (!isset($_SESSION['user_id'])) { - header("Location: login.php"); - exit(); -} - -$userId = $_SESSION['user_id']; +$is_guest = !isset($_SESSION['user_id']); +$user_id = $_SESSION['user_id'] ?? null; +$session_id = session_id(); $pdo = db(); -$stmt = $pdo->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); +$user = []; +if (!$is_guest) { + $userStmt = $pdo->prepare("SELECT name, email, address, phone FROM users WHERE id = ?"); + $userStmt->execute([$user_id]); + $user = $userStmt->fetch(PDO::FETCH_ASSOC); +} + +// Fetch cart items +if (!$is_guest) { + $stmt = $pdo->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', $user_id); +} else { + $stmt = $pdo->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.session_id = :session_id"); + $stmt->bindParam(':session_id', $session_id); +} $stmt->execute(); $cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -21,144 +31,216 @@ if (empty($cartItems)) { exit(); } -$totalPrice = 0; +$subtotal = 0; foreach ($cartItems as $item) { - $totalPrice += $item['price'] * $item['quantity']; + $subtotal += $item['price'] * $item['quantity']; } -// Fetch settings from the database $settingsStmt = $pdo->query("SELECT name, value FROM settings WHERE name IN ('delivery_fee', 'service_fee_percentage')"); $settings = $settingsStmt->fetchAll(PDO::FETCH_KEY_PAIR); $delivery_fee = $settings['delivery_fee'] ?? 0; $service_fee_percentage = $settings['service_fee_percentage'] ?? 0; +$service_fee = ($subtotal * $service_fee_percentage) / 100; -$service_fee = ($totalPrice * $service_fee_percentage) / 100; -$totalPriceWithFees = $totalPrice + $delivery_fee + $service_fee; - +$discount_amount = $_SESSION['discount_amount'] ?? 0; +$totalPrice = $subtotal + $delivery_fee + $service_fee - $discount_amount; +$_SESSION['total_price'] = $totalPrice; include 'header.php'; ?> - + -
$
- -This restaurant has no menu items yet.
-""
+ +This restaurant has no reviews yet.
+ - -Restaurant not found.
- + + Leave a Review + +Log in to leave a review.
+ +Your order has been placed successfully.
-Your Order ID is:
-We have received your order and will begin processing it shortly.
- Continue Shopping +Your order has been placed successfully.
+Your Order ID is:
+
+ Name:
+ Address:
+ Phone:
+
+ Date:
+ Status:
+
We've received your order and will begin processing it shortly. You can track the progress of your order using the button below.
+ Continue Shopping + Track Order +No order specified.
Order not found or you do not have permission to view it.
Restaurant:
-Order Date:
-Status:
+Order #
+Restaurant:
+