|
Server IP : 217.21.85.138 / Your IP : 216.73.216.103 Web Server : LiteSpeed System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64 User : u915722082 ( 915722082) PHP Version : 7.4.33 Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail MySQL : OFF | cURL : ON | WGET : ON | Perl : OFF | Python : OFF Directory (0755) : /home/u915722082/.nvm/../public_html/lohri/user/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<?php
session_start();
require_once __DIR__ . '/../config/config.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
$user_id = $_SESSION['user_id'];
$order_number = $_GET['order'] ?? '';
if (empty($order_number)) {
header("Location: orders.php");
exit();
}
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
} catch (PDOException $e) {
die("❌ Database connection failed: " . htmlspecialchars($e->getMessage()));
}
// Fetch order details
$orderStmt = $pdo->prepare("
SELECT o.*,
u.email,
u.fname,
u.lname
FROM orders o
INNER JOIN tbl_user u ON o.user_id = u.uid
WHERE o.order_number = ? AND o.user_id = ?
");
$orderStmt->execute([$order_number, $user_id]);
$order = $orderStmt->fetch();
if (!$order) {
header("Location: orders.php");
exit();
}
// Fetch order items
$itemsStmt = $pdo->prepare("
SELECT oi.*,
pvo.option_value,
pv.variant_data
FROM order_items oi
LEFT JOIN product_variation_options pvo ON oi.variant_id = pvo.id
LEFT JOIN product_variations pv ON pvo.id = pv.id
WHERE oi.order_id = ?
");
$itemsStmt->execute([$order['order_id']]);
$orderItems = $itemsStmt->fetchAll();
// Fetch shipping details
$shippingStmt = $pdo->prepare("SELECT * FROM order_shipping_details WHERE order_id = ?");
$shippingStmt->execute([$order['order_id']]);
$shipping = $shippingStmt->fetch();
// Order status timeline
$statusTimeline = [
'pending' => ['label' => 'Order Placed', 'icon' => 'fa-check-circle'],
'processing' => ['label' => 'Processing', 'icon' => 'fa-cog'],
'shipped' => ['label' => 'Shipped', 'icon' => 'fa-truck'],
'delivered' => ['label' => 'Delivered', 'icon' => 'fa-box-open'],
];
if ($order['order_status'] === 'cancelled') {
$statusTimeline = [
'pending' => ['label' => 'Order Placed', 'icon' => 'fa-check-circle'],
'cancelled' => ['label' => 'Cancelled', 'icon' => 'fa-times-circle'],
];
}
$currentStatusIndex = array_search($order['order_status'], array_keys($statusTimeline));
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Order Details - <?= htmlspecialchars($order_number) ?></title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<style>
@media (min-width: 1200px) and (max-width: 1599px) {
.insta-highlight-section {
padding: 0px 20px 150px !important;
}
}
/* ============================================
RESET & BASE
============================================ */
body {
background-color: #fff;
color: #000;
}
.order-details-container {
max-width: 1140px;
margin: 40px auto;
padding: 0 20px 100px;
}
/* ============================================
PAGE HEADER
============================================ */
.page-header {
background: transparent;
padding: 0 0 20px 0;
border: none;
margin-bottom: 0;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.back-link {
display: none;
}
.header-left {
flex: 1;
}
.order-date {
font-size: 11px;
color: #666;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 1.5px;
font-weight: 500;
}
.order-title {
font-size: 24px;
font-weight: 400;
margin: 0;
color: #000;
}
.header-right {
padding-top: 10px;
}
.btn-view-invoice {
color: #666;
text-decoration: none;
font-size: 14px;
display: inline-flex;
align-items: center;
gap: 5px;
margin-bottom: 15px;
transition: color 0.3s;
}
/* ============================================
MAIN PRODUCT SECTION
============================================ */
.product-section {
border: 1px solid #e0e0e0;
border-bottom: none;
padding: 0;
margin-bottom: 0;
background: #fff;
}
.product-item {
display: flex;
gap: 30px;
padding: 30px;
border-bottom: 1px solid #e0e0e0;
align-items: flex-start;
}
/* Left side: Image */
.item-image {
width: 160px;
height: 160px;
object-fit: cover;
background: #f5f5f5;
flex-shrink: 0;
}
/* Right side: All details in a grid */
.item-details {
flex: 1;
display: grid;
grid-template-columns: 1fr 200px 200px 120px;
gap: 30px;
align-items: start;
}
.item-info {
padding-top: 5px;
}
.item-name {
font-size: 15px;
font-weight: 500;
margin-bottom: 8px;
color: #000;
}
.item-quantity {
font-size: 13px;
color: #666;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.delivery-address {
padding-top: 5px;
}
.address-title {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
color: #000;
margin-bottom: 12px;
}
.address-name {
font-size: 13px;
font-weight: 500;
color: #000;
margin-bottom: 5px;
}
.address-text {
font-size: 13px;
color: #666;
line-height: 1.6;
}
.shipping-updates {
padding-top: 5px;
}
.updates-title {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
color: #000;
margin-bottom: 12px;
}
.updates-text {
font-size: 13px;
color: #666;
line-height: 1.6;
}
.updates-text a {
color: #000;
text-decoration: underline;
}
.item-price {
font-size: 15px;
font-weight: 600;
color: #000;
text-align: right;
padding-top: 5px;
}
/* ============================================
TIMELINE SECTION - PROGRESS BAR
============================================ */
.timeline-section {
border: 1px solid #e0e0e0;
border-top: 1px solid #e0e0e0;
padding: 40px;
margin-bottom: 40px;
background: #fff;
}
.timeline-header {
font-size: 13px;
font-weight: 500;
color: #000;
/*margin-bottom: 30px;*/
text-transform: uppercase;
letter-spacing: 0.5px;
}
.order-timeline {
position: relative;
padding-top: 35px;
}
/* Timeline labels */
.timeline-labels {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
z-index: 2;
margin-bottom: 15px;
}
.timeline-item {
flex: 1;
text-align: center;
}
.timeline-item:first-child {
text-align: left;
}
.timeline-item:last-child {
text-align: right;
}
.timeline-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
color: #d0d0d0;
white-space: nowrap;
padding-bottom: 20px;
}
.timeline-item.active .timeline-label,
.timeline-item.completed .timeline-label {
color: #000;
}
/* Grey background bar - FULL WIDTH */
.order-timeline::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 6px;
background: #e0e0e0;
z-index: 0;
border-radius: 10px;
}
/* Black progress fill */
.timeline-progress {
position: absolute;
bottom: 0;
left: 0;
height: 6px;
background: #000;
z-index: 1;
transition: width 0.8s ease;
border-radius: 10px;
}
/* ============================================
BOTTOM SECTION (3 COLUMNS)
============================================ */
.bottom-section {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40px;
background: #f8f8f8;
padding: 30px;
}
.info-box {
padding: 0;
}
.info-box-title {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
color: #000;
margin-bottom: 15px;
letter-spacing: 0.5px;
}
.info-name {
font-size: 13px;
font-weight: 500;
color: #000;
margin-bottom: 5px;
}
.info-text {
font-size: 13px;
color: #666;
line-height: 1.8;
}
/* Payment Information */
.payment-method-row {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.visa-badge {
background: #1434CB;
color: #fff;
padding: 3px 8px;
border-radius: 3px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.5px;
}
.card-info {
font-size: 13px;
color: #000;
}
/* Order Summary */
.summary-section {
margin-top: 25px;
}
.summary-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.summary-label {
font-size: 11px;
text-transform: uppercase;
/*letter-spacing: 1px;*/
color: #666;
font-weight: 600;
}
.summary-value {
font-size: 13px;
font-weight: 500;
color: #000;
}
.summary-row.total {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
.summary-row.total .summary-label,
.summary-row.total .summary-value {
font-size: 16px;
font-weight: 600;
color: #000;
}
/* ============================================
CANCEL BUTTON
============================================ */
.btn-cancel-order {
padding: 11px 18px;
background: #dc3545;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
margin-top: 15px;
transition: background 0.3s;
text-transform: capitalize;
letter-spacing: 1px;
}
.btn-cancel-order:hover {
background: #c82333;
}
/* ============================================
MOBILE RESPONSIVE
============================================ */
@media (max-width: 992px) {
.item-details {
grid-template-columns: 1fr 180px 180px 100px;
gap: 20px;
}
}
@media (max-width: 768px) {
.address-title,.updates-title{
font-size: 12px;
margin-bottom: 0px !important;
margin-top: 10px !important;
}
.order-details-container {
padding: 20px 15px 60px;
margin: 20px auto;
}
.page-header {
flex-direction: column;
padding-bottom: 10px;
}
.header-right {
width: 100%;
padding-top: 20px;
}
.order-date {
font-size: 10px;
}
.order-title {
font-size: 22px;
}
/*.btn-view-invoice {*/
/* width: 100%;*/
/* justify-content: center;*/
/* padding: 14px 24px;*/
/*}*/
/* Product Section */
.product-item {
flex-direction: column;
gap: 20px;
padding: 25px 20px;
}
.item-image {
width: 100%;
height: 200px;
}
.item-details {
grid-template-columns: 1fr;
gap: 0px;
}
.item-price {
text-align: left;
font-size: 16px;
}
/* Timeline */
.timeline-section {
padding: 25px 20px;
}
.order-timeline {
padding-top: 35px;
}
.timeline-labels {
margin-bottom: 15px;
}
.timeline-label {
font-size: 9px;
letter-spacing: 0.5px;
}
.order-timeline::before {
height: 3px;
}
.timeline-progress {
height: 3px;
}
/* Bottom Section */
.bottom-section {
grid-template-columns: 1fr;
gap: 30px;
margin-bottom: 50px;
}
.summary-section {
margin-top: 20px;
}
}
@media (max-width: 480px) {
.pb-smm-00 {
padding-bottom: 10px !important;
}
.order-details-container {
padding: 15px 12px 50px;
}
.order-title {
font-size: 20px;
}
.product-item {
padding: 20px 15px;
}
.timeline-section {
padding: 20px 15px;
}
.info-box-title {
font-size: 12px;
}
}
</style>
</head>
<body>
<?php include "../user/header.php"; ?>
<?php include "../ui/nav.php"; ?>
<div class="order-details-container pb-smm-00" style="padding-bottom:100px">
<!-- Page Header -->
<div class="page-header">
<div class="header-left">
<div class="order-date">
<?= strtoupper(date('F d, Y', strtotime($order['created_at']))) ?>
</div>
<h1 class="order-title">Order #<?= htmlspecialchars($order['order_number']) ?></h1>
</div>
<div class="header-right">
<a href="orders.php" class="btn-view-invoice">
<i class="fas fa-arrow-left"></i> Back to Orders
</a>
</div>
</div>
<!-- Product Section -->
<!-- Product Section -->
<div class="product-section">
<?php foreach ($orderItems as $item): ?>
<div class="product-item">
<img src="../Images/Product/<?= htmlspecialchars($item['product_image']) ?>"
alt="<?= htmlspecialchars($item['product_name']) ?>"
class="item-image">
<div class="item-details">
<div class="item-info">
<div class="item-name"><?= htmlspecialchars($item['product_name']) ?></div>
<div class="item-quantity">QTY <?= $item['quantity'] ?></div>
</div>
<div class="delivery-address">
<div class="address-title">DELIVERY ADDRESS</div>
<?php if ($shipping): ?>
<div class="address-name"><?= htmlspecialchars($shipping['first_name'] . ' ' . $shipping['last_name']) ?></div>
<div class="address-text">
<?= htmlspecialchars($shipping['address_1']) ?><br>
<?= htmlspecialchars($shipping['city']) ?>, <?= htmlspecialchars($shipping['province_state']) ?> <?= htmlspecialchars($shipping['postal_zip_code']) ?>
</div>
<?php endif; ?>
</div>
<div class="shipping-updates">
<div class="updates-title">SHIPPING UPDATES</div>
<div class="updates-text">
<?= htmlspecialchars($order['email']) ?><br>
<?php if ($shipping && !empty($shipping['phone'])): ?>
<?= htmlspecialchars($shipping['phone']) ?>
<?php endif; ?>
</div>
</div>
<div class="item-price">
₹<?= number_format($item['subtotal'], 2) ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<!-- END Product Section -->
<!-- Timeline Section SEPARATE -->
<div class="timeline-section">
<div class="timeline-header">
<?php
if ($order['order_status'] === 'processing') {
echo 'PREPARING TO SHIP ON ' . strtoupper(date('F d, Y', strtotime($order['updated_at'] . ' +2 days')));
} elseif ($order['order_status'] === 'cancelled') {
echo 'CANCELLED';
} else {
echo strtoupper($order['order_status']);
}
?>
</div>
<div class="order-timeline">
<?php
$statuses = ['pending', 'processing', 'shipped', 'delivered'];
$currentIndex = array_search($order['order_status'], $statuses);
if ($currentIndex !== false) {
$progressWidth = ($currentIndex / (count($statuses) - 1)) * 100;
} else {
$progressWidth = 0;
}
$labels = [
'pending' => 'ORDER PLACED',
'processing' => 'PROCESSING',
'shipped' => 'SHIPPED',
'delivered' => 'DELIVERED'
];
?>
<div class="timeline-labels">
<?php foreach ($statuses as $index => $status):
$isCompleted = $currentIndex !== false && $index < $currentIndex;
$isActive = $status === $order['order_status'];
$itemClass = $isCompleted ? 'completed' : ($isActive ? 'active' : '');
?>
<div class="timeline-item <?= $itemClass ?>">
<div class="timeline-label"><?= $labels[$status] ?></div>
</div>
<?php endforeach; ?>
</div>
<div class="timeline-progress" style="width: <?= $progressWidth ?>%"></div>
</div>
</div>
<!-- Timeline Section -->
<!-- Bottom Section (3 Columns) -->
<div class="bottom-section">
<!-- Billing Address -->
<div class="info-box">
<div class="info-box-title">BILLING ADDRESS</div>
<?php if ($shipping): ?>
<div class="info-name"><?= htmlspecialchars($shipping['first_name'] . ' ' . $shipping['last_name']) ?></div>
<div class="info-text">
<?= htmlspecialchars($shipping['address_1']) ?><br>
<?= htmlspecialchars($shipping['city']) ?>, <?= htmlspecialchars($shipping['province_state']) ?> <?= htmlspecialchars($shipping['postal_zip_code']) ?>
</div>
<?php endif; ?>
</div>
<!-- Payment Information -->
<div class="info-box">
<div class="info-box-title">PAYMENT INFORMATION</div>
<div class="payment-method-row">
<?php if ($order['payment_method'] === 'card'): ?>
<span class="visa-badge">VISA</span>
<span class="card-info">ENDING WITH 4242</span>
<?php else: ?>
<span class="card-info"><?= strtoupper($order['payment_method']) ?></span>
<?php endif; ?>
</div>
<div class="info-text">
<?php if ($order['payment_method'] === 'card'): ?>
EXPIRES 02 / 24
<?php endif; ?>
</div>
<?php if ($order['order_status'] === 'pending' || $order['order_status'] === 'processing'): ?>
<button onclick="cancelOrder()" class="btn-cancel-order">
Cancel Order
</button>
<?php endif; ?>
</div>
<!-- Order Summary -->
<div class="info-box">
<div class="info-box-title">ORDER SUMMARY</div>
<div class="summary-section">
<div class="summary-row">
<span class="summary-label">SUBTOTAL</span>
<span class="summary-value">₹<?= number_format($order['subtotal'], 2) ?></span>
</div>
<div class="summary-row">
<span class="summary-label">SHIPPING</span>
<span class="summary-value">
<?= $order['shipping_cost'] > 0 ? '₹' . number_format($order['shipping_cost'], 2) : '₹0.00' ?>
</span>
</div>
<div class="summary-row">
<span class="summary-label">TAX</span>
<span class="summary-value">₹<?= number_format($order['tax_amount'], 2) ?></span>
</div>
<div class="summary-row total">
<span class="summary-label">ORDER TOTAL</span>
<span class="summary-value">₹<?= number_format($order['total_amount'], 2) ?></span>
</div>
</div>
</div>
</div>
</div>
<?php include "../ui/footer.php"; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
async function cancelOrder() {
if (!confirm('Are you sure you want to cancel this order?')) return;
try {
const res = await fetch('cancel_order.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ order_number: '<?= htmlspecialchars($order['order_number']) ?>' })
});
const text = await res.text();
let data;
try {
data = JSON.parse(text);
} catch (e) {
console.error('Server response:', text);
data = { success: false, message: 'Invalid server response' };
}
if (data.success) {
alert(data.message || 'Order cancelled successfully');
location.reload();
} else {
alert(data.message || 'Failed to cancel order');
}
} catch (err) {
console.error('Cancel order error:', err);
alert('Network error: Unable to cancel order');
}
}
</script>
</body>
</html>