Files
2026-05-16 23:00:37 -05:00

198 lines
8.2 KiB
PHP

<?php
/**
* Tom's Java Jive - Admin Dashboard
*/
$pageTitle = 'Dashboard';
require_once __DIR__ . '/includes/header.php';
// Get stats
$totalOrders = db()->count('orders');
$todayOrders = db()->count('orders', 'DATE(created_at) = CURDATE()');
$totalRevenue = db()->fetch("SELECT COALESCE(SUM(total), 0) as total FROM orders WHERE payment_status = 'paid'")['total'] ?? 0;
$todayRevenue = db()->fetch("SELECT COALESCE(SUM(total), 0) as total FROM orders WHERE payment_status = 'paid' AND DATE(created_at) = CURDATE()")['total'] ?? 0;
$totalCustomers = db()->count('customers');
$totalProducts = db()->count('products', 'is_active = 1');
$lowStockProducts = db()->count('products', 'stock <= low_stock_threshold AND is_active = 1');
$pendingOrders = db()->count('orders', "order_status = 'pending'");
// Recent orders
$recentOrders = db()->fetchAll(
"SELECT * FROM orders ORDER BY created_at DESC LIMIT 10"
);
// Low stock products
$lowStockItems = db()->fetchAll(
"SELECT * FROM products WHERE stock <= low_stock_threshold AND is_active = 1 ORDER BY stock ASC LIMIT 5"
);
?>
<div class="page-header">
<h1 class="page-title">Dashboard</h1>
<span class="text-muted"><?= date('l, F j, Y') ?></span>
</div>
<!-- Stats Cards -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-card-icon primary">
<i class="fas fa-dollar-sign"></i>
</div>
<div class="stat-card-value"><?= formatCurrency($todayRevenue) ?></div>
<div class="stat-card-label">Today's Revenue</div>
</div>
<div class="stat-card">
<div class="stat-card-icon success">
<i class="fas fa-shopping-cart"></i>
</div>
<div class="stat-card-value"><?= $todayOrders ?></div>
<div class="stat-card-label">Today's Orders</div>
</div>
<div class="stat-card">
<div class="stat-card-icon warning">
<i class="fas fa-users"></i>
</div>
<div class="stat-card-value"><?= $totalCustomers ?></div>
<div class="stat-card-label">Total Customers</div>
</div>
<div class="stat-card">
<div class="stat-card-icon <?= $pendingOrders > 0 ? 'error' : 'primary' ?>">
<i class="fas fa-clock"></i>
</div>
<div class="stat-card-value"><?= $pendingOrders ?></div>
<div class="stat-card-label">Pending Orders</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem;">
<!-- Recent Orders -->
<div class="admin-card">
<div class="admin-card-header">
<h3 class="admin-card-title">Recent Orders</h3>
<a href="/admin/orders.php" class="btn btn-sm btn-secondary">View All</a>
</div>
<div class="admin-card-body" style="padding: 0;">
<table class="admin-table">
<thead>
<tr>
<th>Order</th>
<th>Customer</th>
<th>Total</th>
<th>Status</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php if (empty($recentOrders)): ?>
<tr>
<td colspan="5" class="text-muted" style="text-align: center; padding: 2rem;">
No orders yet
</td>
</tr>
<?php else: ?>
<?php foreach ($recentOrders as $order): ?>
<tr>
<td>
<a href="/admin/order.php?id=<?= $order['order_id'] ?>">
<?= htmlspecialchars($order['order_number']) ?>
</a>
</td>
<td><?= htmlspecialchars($order['customer_name'] ?? $order['customer_email']) ?></td>
<td><?= formatCurrency($order['total']) ?></td>
<td>
<?php
$statusClass = match($order['order_status']) {
'pending' => 'warning',
'confirmed', 'processing' => 'primary',
'shipped', 'delivered' => 'success',
'cancelled', 'refunded' => 'error',
default => 'primary'
};
?>
<span class="badge badge-<?= $statusClass ?>">
<?= ucfirst($order['order_status']) ?>
</span>
</td>
<td class="text-muted"><?= formatDate($order['created_at']) ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Sidebar Stats -->
<div>
<!-- Quick Stats -->
<div class="admin-card">
<div class="admin-card-header">
<h3 class="admin-card-title">Overview</h3>
</div>
<div class="admin-card-body">
<div style="display: flex; justify-content: space-between; margin-bottom: 1rem;">
<span>Total Revenue</span>
<strong><?= formatCurrency($totalRevenue) ?></strong>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 1rem;">
<span>Total Orders</span>
<strong><?= $totalOrders ?></strong>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 1rem;">
<span>Active Products</span>
<strong><?= $totalProducts ?></strong>
</div>
<div style="display: flex; justify-content: space-between;">
<span>Low Stock Items</span>
<strong class="<?= $lowStockProducts > 0 ? 'text-error' : '' ?>"><?= $lowStockProducts ?></strong>
</div>
</div>
</div>
<!-- Low Stock Alert -->
<?php if (!empty($lowStockItems)): ?>
<div class="admin-card">
<div class="admin-card-header">
<h3 class="admin-card-title">
<i class="fas fa-exclamation-triangle text-warning"></i> Low Stock
</h3>
</div>
<div class="admin-card-body">
<?php foreach ($lowStockItems as $item): ?>
<div style="display: flex; justify-content: space-between; margin-bottom: 0.75rem;">
<span><?= htmlspecialchars(truncate($item['name'], 25)) ?></span>
<span class="badge badge-error"><?= $item['stock'] ?> left</span>
</div>
<?php endforeach; ?>
<a href="/admin/inventory.php" class="btn btn-sm btn-secondary btn-block mt-1">
Manage Inventory
</a>
</div>
</div>
<?php endif; ?>
<!-- Quick Actions -->
<div class="admin-card">
<div class="admin-card-header">
<h3 class="admin-card-title">Quick Actions</h3>
</div>
<div class="admin-card-body">
<a href="/admin/product-edit.php" class="btn btn-primary btn-block mb-1">
<i class="fas fa-plus"></i> Add Product
</a>
<a href="/admin/pos.php" class="btn btn-secondary btn-block mb-1">
<i class="fas fa-cash-register"></i> Open POS
</a>
<a href="/admin/orders.php?status=pending" class="btn btn-secondary btn-block">
<i class="fas fa-clock"></i> Pending Orders
</a>
</div>
</div>
</div>
</div>
<?php require_once __DIR__ . '/includes/footer.php'; ?>