169 lines
6.5 KiB
PHP
169 lines
6.5 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../db/config.php';
|
|
require_once __DIR__ . '/../includes/functions.php';
|
|
|
|
$pdo = db();
|
|
|
|
// Fetch Dashboard Stats
|
|
$today = date('Y-m-d');
|
|
|
|
// Total Revenue Today
|
|
$stmt = $pdo->prepare("SELECT SUM(total_amount) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'");
|
|
$stmt->execute([$today]);
|
|
$revenueToday = $stmt->fetchColumn() ?: 0;
|
|
|
|
// Total Orders Today
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE DATE(created_at) = ?");
|
|
$stmt->execute([$today]);
|
|
$ordersToday = $stmt->fetchColumn();
|
|
|
|
// Active Outlets
|
|
$outletsCount = $pdo->query("SELECT COUNT(*) FROM outlets")->fetchColumn();
|
|
|
|
// Total Products
|
|
$productsCount = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();
|
|
|
|
// Recent Orders
|
|
$recentOrders = $pdo->query("SELECT o.*,
|
|
(SELECT GROUP_CONCAT(p.name SEPARATOR ', ') FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = o.id) as items
|
|
FROM orders o ORDER BY created_at DESC LIMIT 5")->fetchAll();
|
|
|
|
include 'includes/header.php';
|
|
?>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h2 class="fw-bold mb-1">Dashboard</h2>
|
|
<p class="text-muted">Welcome back, <?= htmlspecialchars($userName) ?>!</p>
|
|
</div>
|
|
<div>
|
|
<a href="orders.php" class="btn btn-primary"><i class="bi bi-plus-lg me-1"></i> New Order</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-4">
|
|
<!-- Revenue Card -->
|
|
<div class="col-md-3">
|
|
<div class="card stat-card h-100 p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="icon-box bg-success bg-opacity-10 text-success me-3">
|
|
<i class="bi bi-currency-dollar"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="text-muted mb-0">Today's Revenue</h6>
|
|
<h3 class="fw-bold mb-0">$<?= number_format($revenueToday, 2) ?></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Orders Card -->
|
|
<div class="col-md-3">
|
|
<div class="card stat-card h-100 p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="icon-box bg-primary bg-opacity-10 text-primary me-3">
|
|
<i class="bi bi-receipt"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="text-muted mb-0">Orders Today</h6>
|
|
<h3 class="fw-bold mb-0"><?= $ordersToday ?></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Outlets Card -->
|
|
<div class="col-md-3">
|
|
<div class="card stat-card h-100 p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="icon-box bg-warning bg-opacity-10 text-warning me-3">
|
|
<i class="bi bi-shop"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="text-muted mb-0">Active Outlets</h6>
|
|
<h3 class="fw-bold mb-0"><?= $outletsCount ?></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Products Card -->
|
|
<div class="col-md-3">
|
|
<div class="card stat-card h-100 p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="icon-box bg-info bg-opacity-10 text-info me-3">
|
|
<i class="bi bi-box-seam"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="text-muted mb-0">Total Products</h6>
|
|
<h3 class="fw-bold mb-0"><?= $productsCount ?></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Orders Table -->
|
|
<div class="card border-0 shadow-sm rounded-3">
|
|
<div class="card-header bg-white border-bottom py-3">
|
|
<h5 class="mb-0 fw-bold">Recent Orders</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">ID</th>
|
|
<th>Type</th>
|
|
<th>Table/Customer</th>
|
|
<th>Total</th>
|
|
<th>Status</th>
|
|
<th>Date</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($recentOrders as $order): ?>
|
|
<tr>
|
|
<td class="ps-4 fw-medium">#<?= $order['id'] ?></td>
|
|
<td>
|
|
<?php
|
|
$badge = match($order['order_type']) {
|
|
'dine-in' => 'bg-info',
|
|
'takeaway' => 'bg-success',
|
|
'delivery' => 'bg-warning',
|
|
'drive-thru' => 'bg-purple',
|
|
default => 'bg-secondary'
|
|
};
|
|
?>
|
|
<span class="badge <?= $badge ?> text-dark bg-opacity-25 border border-<?= str_replace('bg-', '', $badge) ?>"><?= ucfirst($order['order_type']) ?></span>
|
|
</td>
|
|
<td>
|
|
<?php if ($order['table_number']): ?>
|
|
Table <?= htmlspecialchars($order['table_number']) ?>
|
|
<?php else: ?>
|
|
<?= htmlspecialchars($order['customer_name'] ?? 'Guest') ?>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="fw-bold">$<?= number_format((float)$order['total_amount'], 2) ?></td>
|
|
<td>
|
|
<span class="status-badge status-<?= $order['status'] ?> badge rounded-pill">
|
|
<?= ucfirst($order['status']) ?>
|
|
</span>
|
|
</td>
|
|
<td class="text-muted small"><?= date('M d, H:i', strtotime($order['created_at'])) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php if (empty($recentOrders)): ?>
|
|
<tr><td colspan="6" class="text-center py-4 text-muted">No recent orders found.</td></tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer bg-white text-center py-3">
|
|
<a href="orders.php" class="text-decoration-none fw-medium">View All Orders</a>
|
|
</div>
|
|
</div>
|
|
|
|
<?php include 'includes/footer.php'; ?>
|