/home/awneajlw/www/codestechvista.com/pending-orders.php
<?php
/**
* Pending Orders Page - Order Management
* This page displays all pending orders in a table format
* Features: Order listing, status updates, view/delete actions, responsive design
*/
// Start session if not already started
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// Include required files
require_once 'config/database.php'; // Database connection configuration
require_once 'includes/auth.php'; // Authentication functions
require_once 'includes/currency_helper.php'; // Currency helper functions
/**
* Authentication Check
* Redirect to welcome page if user is not logged in
*/
if (!isLoggedIn()) {
header('Location: welcome.php');
exit();
}
// Initialize variables for order management
$orders = []; // Array to store pending orders
$error_message = ''; // Error message for failed operations
$success_message = ''; // Success message for completed operations
// Date filtering parameters
$start_date = $_GET['start_date'] ?? date('Y-m-01'); // Default to start of current month
$end_date = $_GET['end_date'] ?? date('Y-m-t'); // Default to end of current month
/**
* Mark Order as Complete Handler
* Process POST request to update order status to 'Completed'
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'mark_complete') {
$order_id = isset($_POST['order_id']) ? (int)$_POST['order_id'] : 0;
if ($order_id > 0) {
try {
$database = new Database();
$db = $database->getConnection();
$user_id = $_SESSION['user_id'];
$update_query = "UPDATE orders SET status = 'Completed' WHERE id = ? AND user_id = ?";
$stmt = $db->prepare($update_query);
$stmt->execute([$order_id, $user_id]);
if ($stmt->rowCount() > 0) {
$success_message = 'Order marked as completed successfully!';
} else {
$error_message = 'Failed to update order status.';
}
} catch (Exception $e) {
$error_message = 'Database error: ' . $e->getMessage();
}
}
}
/**
* Fetch Pending Orders
* Retrieve all pending orders for the current user
*/
try {
$database = new Database();
$db = $database->getConnection();
$user_id = $_SESSION['user_id'];
// Get user's currency
$user_currency = getUserCurrency($db, $user_id);
// Add status column if it doesn't exist (backward compatibility)
try {
$alter_query = "ALTER TABLE orders ADD COLUMN status VARCHAR(50) DEFAULT 'Pending'";
$db->exec($alter_query);
} catch (PDOException $e) {
// Column already exists, ignore error
}
// Fetch pending orders with date filtering
$query = "SELECT
id,
tracking_id,
patient_name,
total_amount,
advance,
balance,
COALESCE(status, 'Pending') as status,
created_at
FROM orders
WHERE user_id = ?
AND (status IS NULL OR status = 'Pending' OR status = '')
AND DATE(created_at) BETWEEN ? AND ?
ORDER BY created_at DESC";
$stmt = $db->prepare($query);
$stmt->execute([$user_id, $start_date, $end_date]);
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
$error_message = 'Error fetching orders: ' . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pending Orders - OPTI SLIP</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/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">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background: white;
min-height: 100vh;
padding: 10px;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0;
}
.header-section {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding: 15px 0;
}
.back-btn {
background: none;
border: none;
color: black;
font-size: 28px;
cursor: pointer;
padding: 12px;
transition: all 0.3s ease;
}
.back-btn:hover {
color: #169D53;
transform: translateX(-3px);
}
.logo-section {
text-align: center;
}
.logo-image {
width: 100%;
height: 120px;
object-fit: contain;
filter: brightness(0) saturate(100%);
}
.date-filter {
display: flex;
align-items: center;
gap: 12px;
font-size: 16px;
color: #666;
background: #f8f9fa;
padding: 12px 18px;
border-radius: 25px;
border: 1px solid #e9ecef;
}
.orders-table-container {
background: white;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
.orders-table {
width: 100%;
border-collapse: collapse;
font-size: 16px;
}
.orders-table th {
background: #f8f9fa;
color: #333;
font-weight: 600;
padding: 18px 12px;
text-align: left;
border-bottom: 2px solid #e9ecef;
font-size: 15px;
}
.orders-table td {
padding: 18px 12px;
border-bottom: 1px solid #f0f0f0;
color: #333;
font-size: 15px;
}
.orders-table tr:hover {
background: #f8f9fa;
}
.status-badge {
background: #ffc107;
color: #000;
padding: 6px 12px;
border-radius: 15px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
}
.action-buttons {
display: flex;
gap: 8px;
align-items: center;
}
.action-btn {
width: 32px;
height: 32px;
border-radius: 50%;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
transition: all 0.3s ease;
}
.view-btn {
background: #28a745;
color: white;
}
.view-btn:hover {
background: #218838;
transform: scale(1.1);
}
.complete-btn {
background: #17a2b8;
color: white;
}
.complete-btn:hover {
background: #138496;
transform: scale(1.1);
}
.alert {
padding: 15px 20px;
border-radius: 10px;
margin-bottom: 25px;
font-size: 15px;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-danger {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.no-orders {
text-align: center;
padding: 40px 20px;
color: #666;
}
.no-orders i {
font-size: 48px;
color: #ddd;
margin-bottom: 15px;
}
/* Mobile Responsive */
@media (max-width: 768px) {
body {
padding: 5px;
}
.header-section {
flex-direction: column;
gap: 10px;
text-align: center;
}
.back-btn {
position: absolute;
left: 10px;
top: 10px;
}
.date-filter {
font-size: 11px;
padding: 6px 10px;
}
.orders-table-container {
overflow-x: auto;
}
.orders-table {
min-width: 800px;
font-size: 11px;
}
.orders-table th,
.orders-table td {
padding: 8px 4px;
font-size: 10px;
}
.action-btn {
width: 20px;
height: 20px;
font-size: 8px;
}
.status-badge {
font-size: 8px;
padding: 2px 6px;
}
}
@media (max-width: 480px) {
.logo-image {
width: 50px;
height: 50px;
}
.orders-table {
min-width: 700px;
}
.orders-table th,
.orders-table td {
padding: 6px 3px;
font-size: 9px;
}
.action-btn {
width: 18px;
height: 18px;
font-size: 7px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header-section">
<button class="back-btn" onclick="window.location.href='home.php'">
<i class="fas fa-arrow-left"></i>
</button>
<div class="logo-section">
<img src="assets/images/Optislipimage.png" alt="Opti Slip Logo" class="logo-image" onerror="this.style.display='none'; this.parentElement.innerHTML='<div style=\'color: black; font-size: 16px; font-weight: bold;\'>OPTI SLIP</div>'">
</div>
<div class="date-filter" onclick="toggleDatePicker()">
<i class="fas fa-calendar-alt"></i>
<span id="dateDisplay"><?php echo date('M j', strtotime($start_date)) . ' To ' . date('M j', strtotime($end_date)); ?></span>
<i class="fas fa-chevron-down"></i>
</div>
</div>
<!-- Success/Error Messages -->
<?php if ($success_message): ?>
<div class="alert alert-success">
<i class="fas fa-check-circle me-2"></i>
<?php echo htmlspecialchars($success_message); ?>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle me-2"></i>
<?php echo htmlspecialchars($error_message); ?>
</div>
<?php endif; ?>
<div class="orders-table-container">
<?php if (empty($orders)): ?>
<div class="no-orders">
<i class="fas fa-inbox"></i>
<h5>No Pending Orders</h5>
<p>You don't have any pending orders at the moment.</p>
</div>
<?php else: ?>
<table class="orders-table">
<thead>
<tr>
<th>UID</th>
<th>Patient Name</th>
<th>Tracking Id</th>
<th>Amount</th>
<th>Advance</th>
<th>Balance</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$uid_counter = 1;
foreach ($orders as $order):
$uid = 'UI' . str_pad($uid_counter, 3, '0', STR_PAD_LEFT);
$uid_counter++;
?>
<tr>
<td><?php echo htmlspecialchars($uid); ?></td>
<td><?php echo htmlspecialchars($order['patient_name']); ?></td>
<td><?php echo htmlspecialchars($order['tracking_id'] ?? 'N/A'); ?></td>
<td><?php echo formatCurrency($order['total_amount'] ?? 0, $user_currency); ?></td>
<td><?php echo formatCurrency($order['advance'] ?? 0, $user_currency); ?></td>
<td><?php echo formatCurrency($order['balance'] ?? 0, $user_currency); ?></td>
<td>
<span class="status-badge">
<?php echo htmlspecialchars($order['status'] ?? 'Pending'); ?>
</span>
</td>
<td>
<div class="action-buttons">
<button class="action-btn view-btn"
onclick="window.location.href='pending-order-details.php?id=<?php echo $order['id']; ?>'"
title="View Order">
<i class="fas fa-eye"></i>
</button>
<button class="action-btn complete-btn"
onclick="markComplete(<?php echo $order['id']; ?>)"
title="Mark as Complete">
<i class="fas fa-check"></i>
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<!-- Hidden form for marking orders as complete -->
<form id="completeForm" method="POST" style="display: none;">
<input type="hidden" name="action" value="mark_complete">
<input type="hidden" name="order_id" id="completeOrderId">
</form>
<script>
function markComplete(orderId) {
if (confirm('Are you sure you want to mark this order as completed?')) {
document.getElementById('completeOrderId').value = orderId;
document.getElementById('completeForm').submit();
}
}
// Auto-hide alerts after 5 seconds
setTimeout(() => {
const alerts = document.querySelectorAll('.alert');
alerts.forEach(alert => {
alert.style.opacity = '0';
alert.style.transition = 'opacity 0.5s ease';
setTimeout(() => alert.remove(), 500);
});
}, 5000);
// Date picker functionality
function toggleDatePicker() {
const modal = document.getElementById('datePickerModal');
if (modal) {
if (modal.style.display === 'flex') {
modal.style.display = 'none';
} else {
modal.style.display = 'flex';
}
}
}
function closeDatePicker() {
document.getElementById('datePickerModal').style.display = 'none';
}
function applyDateFilter() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
if (startDate && endDate) {
window.location.href = `pending-orders.php?start_date=${startDate}&end_date=${endDate}`;
}
}
function setQuickRange(days) {
const endDate = new Date();
const startDate = new Date();
startDate.setDate(endDate.getDate() - days);
const formatDate = (date) => date.toISOString().split('T')[0];
document.getElementById('startDate').value = formatDate(startDate);
document.getElementById('endDate').value = formatDate(endDate);
}
</script>
<!-- Date Picker Modal -->
<div id="datePickerModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; justify-content: center; align-items: center;">
<div style="background: white; padding: 30px; border-radius: 15px; max-width: 400px; width: 90%; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<h3 style="margin: 0; color: #333;">Select Date Range</h3>
<button onclick="closeDatePicker()" style="background: none; border: none; font-size: 20px; cursor: pointer; color: #999;">×</button>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold; color: #555;">Start Date:</label>
<input type="date" id="startDate" value="<?php echo $start_date; ?>" style="width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 8px;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold; color: #555;">End Date:</label>
<input type="date" id="endDate" value="<?php echo $end_date; ?>" style="width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 8px;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 10px; font-weight: bold; color: #555;">Quick Ranges:</label>
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
<button onclick="setQuickRange(0)" style="padding: 8px 12px; background: #f0f0f0; border: 1px solid #ddd; border-radius: 5px; cursor: pointer;">Today</button>
<button onclick="setQuickRange(7)" style="padding: 8px 12px; background: #f0f0f0; border: 1px solid #ddd; border-radius: 5px; cursor: pointer;">Last 7 Days</button>
<button onclick="setQuickRange(30)" style="padding: 8px 12px; background: #f0f0f0; border: 1px solid #ddd; border-radius: 5px; cursor: pointer;">Last 30 Days</button>
</div>
</div>
<div style="display: flex; gap: 10px; justify-content: flex-end;">
<button onclick="closeDatePicker()" style="padding: 10px 20px; background: #f0f0f0; border: 1px solid #ddd; border-radius: 8px; cursor: pointer;">Cancel</button>
<button onclick="applyDateFilter()" style="padding: 10px 20px; background: #169D53; color: white; border: none; border-radius: 8px; cursor: pointer;">Apply Filter</button>
</div>
</div>
</div>
</body>
</html>