266 lines
11 KiB
PHP
266 lines
11 KiB
PHP
<?php
|
|
$title = 'dashboard';
|
|
require_once __DIR__ . '/includes/header.php';
|
|
|
|
// Stats logic
|
|
$branch_id = $_SESSION['branch_id'];
|
|
$is_super = ($current_role === 'super_admin');
|
|
$is_limited = ($current_role === 'limited_viewer');
|
|
|
|
// For super_admin, "all" means no branch filtering.
|
|
// Otherwise, we filter by the selected branch.
|
|
$filter_branch = ($branch_id !== 'all');
|
|
|
|
if (!$is_limited) {
|
|
$stats = [
|
|
'today_revenue' => 0,
|
|
'active_orders' => 0,
|
|
'new_customers' => 0,
|
|
'ready_orders' => 0,
|
|
];
|
|
|
|
// Today's revenue
|
|
$rev_where = !$filter_branch ? "" : " AND order_id IN (SELECT id FROM orders WHERE branch_id = ?)";
|
|
$rev_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT SUM(amount) as total FROM payments WHERE created_at >= CURDATE() $rev_where");
|
|
$stmt->execute($rev_params);
|
|
$stats['today_revenue'] = $stmt->fetch()['total'] ?? 0;
|
|
|
|
// Active orders (received, processing)
|
|
$ord_where = !$filter_branch ? "WHERE status IN ('received', 'processing')" : "WHERE branch_id = ? AND status IN ('received', 'processing')";
|
|
$ord_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT COUNT(*) as count FROM orders $ord_where");
|
|
$stmt->execute($ord_params);
|
|
$stats['active_orders'] = $stmt->fetch()['count'] ?? 0;
|
|
|
|
// Ready orders
|
|
$ready_where = !$filter_branch ? "WHERE status = 'ready'" : "WHERE branch_id = ? AND status = 'ready'";
|
|
$ready_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT COUNT(*) as count FROM orders $ready_where");
|
|
$stmt->execute($ready_params);
|
|
$stats['ready_orders'] = $stmt->fetch()['count'] ?? 0;
|
|
|
|
// New customers today
|
|
$cust_where = !$filter_branch ? "WHERE created_at >= CURDATE()" : "WHERE branch_id = ? AND created_at >= CURDATE()";
|
|
$cust_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT COUNT(*) as count FROM customers $cust_where");
|
|
$stmt->execute($cust_params);
|
|
$stats['new_customers'] = $stmt->fetch()['count'] ?? 0;
|
|
|
|
// Monthly Orders (Last 12 months)
|
|
$monthly_where = !$filter_branch ? "WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)" : "WHERE branch_id = ? AND created_at >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)";
|
|
$monthly_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT DATE_FORMAT(created_at, '%Y-%m') as month_year, COUNT(*) as count
|
|
FROM orders
|
|
$monthly_where
|
|
GROUP BY month_year
|
|
ORDER BY month_year ASC");
|
|
$stmt->execute($monthly_params);
|
|
$monthly_orders = $stmt->fetchAll();
|
|
|
|
// Charts data for Dashboard (Last 7 days)
|
|
$chart_where = !$filter_branch ? "WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)" : "WHERE branch_id = ? AND created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
|
|
$chart_params = !$filter_branch ? [] : [$branch_id];
|
|
|
|
// Daily Revenue
|
|
$stmt = db()->prepare("SELECT DATE(created_at) as date, SUM(total_price) as revenue
|
|
FROM orders
|
|
$chart_where
|
|
GROUP BY DATE(created_at)
|
|
ORDER BY DATE(created_at) ASC");
|
|
$stmt->execute($chart_params);
|
|
$daily_revenue = $stmt->fetchAll();
|
|
|
|
// Orders by Status (All time or current)
|
|
$status_where = !$filter_branch ? "" : "WHERE branch_id = ?";
|
|
$status_params = !$filter_branch ? [] : [$branch_id];
|
|
$stmt = db()->prepare("SELECT status, COUNT(*) as count FROM orders $status_where GROUP BY status");
|
|
$stmt->execute($status_params);
|
|
$orders_by_status = $stmt->fetchAll();
|
|
}
|
|
?>
|
|
|
|
<?php if ($is_limited): ?>
|
|
<div class="d-flex flex-column align-items-center justify-content-center" style="min-height: 60vh;">
|
|
<div class="text-center p-5 card shadow-sm" style="border-radius: 30px; max-width: 600px;">
|
|
<?php if ($company_info['logo']): ?>
|
|
<img src="<?= $company_info['logo'] ?>" alt="Logo" class="img-fluid mb-4" style="max-height: 150px;">
|
|
<?php endif; ?>
|
|
<h1 class="fw-bold text-primary mb-3">
|
|
<?= htmlspecialchars(is_arabic() ? $company_info['name_ar'] : $company_info['name_en']) ?>
|
|
</h1>
|
|
<p class="text-muted fs-5">
|
|
<?= is_arabic() ? 'مرحباً بك في لوحة التحكم' : 'Welcome to your dashboard' ?>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="bg-primary text-white p-3 rounded-4 me-3">
|
|
<i class="bi bi-cash-stack fs-3"></i>
|
|
</div>
|
|
<div>
|
|
<div class="text-muted small"><?= __('today_revenue') ?></div>
|
|
<div class="fw-bold fs-5"><?= format_amount($stats['today_revenue']) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="bg-warning text-white p-3 rounded-4 me-3">
|
|
<i class="bi bi-clock-history fs-3"></i>
|
|
</div>
|
|
<div>
|
|
<div class="text-muted small"><?= __('active_orders') ?></div>
|
|
<div class="fw-bold fs-5"><?= $stats['active_orders'] ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="bg-success text-white p-3 rounded-4 me-3">
|
|
<i class="bi bi-check-circle fs-3"></i>
|
|
</div>
|
|
<div>
|
|
<div class="text-muted small"><?= __('ready_orders') ?></div>
|
|
<div class="fw-bold fs-5"><?= $stats['ready_orders'] ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card p-3">
|
|
<div class="d-flex align-items-center">
|
|
<div class="bg-info text-white p-3 rounded-4 me-3">
|
|
<i class="bi bi-people fs-3"></i>
|
|
</div>
|
|
<div>
|
|
<div class="text-muted small"><?= __('new_customers') ?></div>
|
|
<div class="fw-bold fs-5"><?= $stats['new_customers'] ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-md-8">
|
|
<div class="card p-4 h-100">
|
|
<h6 class="fw-bold mb-4"><?= __('revenue_last_7_days') ?? 'Revenue (Last 7 Days)' ?></h6>
|
|
<canvas id="revenueChart" height="100"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card p-4 h-100">
|
|
<h6 class="fw-bold mb-4"><?= __('orders_by_status') ?></h6>
|
|
<canvas id="statusChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-md-8">
|
|
<div class="card p-4 h-100">
|
|
<h5 class="fw-bold mb-4"><?= __('orders_per_month') ?></h5>
|
|
<canvas id="monthlyOrdersChart" height="120"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card p-4 h-100 bg-primary text-white">
|
|
<h5 class="fw-bold mb-4"><?= __('quick_actions') ?></h5>
|
|
<a href="pos.php" class="btn btn-light w-100 mb-3 text-start py-3 px-4" style="border-radius: 15px; font-weight: 600;">
|
|
<i class="bi bi-plus-circle-fill me-2"></i> <?= __('new_order') ?>
|
|
</a>
|
|
<a href="customers.php" class="btn btn-light w-100 mb-3 text-start py-3 px-4" style="border-radius: 15px; font-weight: 600;">
|
|
<i class="bi bi-person-plus-fill me-2"></i> <?= __('add_new_customer') ?>
|
|
</a>
|
|
<a href="reports.php" class="btn btn-light w-100 text-start py-3 px-4" style="border-radius: 15px; font-weight: 600;">
|
|
<i class="bi bi-file-earmark-bar-graph-fill me-2"></i> <?= __('reports') ?>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script>
|
|
// Revenue Chart
|
|
if (document.getElementById('revenueChart')) {
|
|
new Chart(document.getElementById('revenueChart'), {
|
|
type: 'line',
|
|
data: {
|
|
labels: <?= json_encode(array_column($daily_revenue, 'date')) ?>,
|
|
datasets: [{
|
|
label: '<?= __('revenue') ?>',
|
|
data: <?= json_encode(array_column($daily_revenue, 'revenue')) ?>,
|
|
borderColor: '#3b82f6',
|
|
backgroundColor: 'rgba(59, 130, 246, 0.1)',
|
|
fill: true,
|
|
tension: 0.4
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: { legend: { display: false } },
|
|
scales: { y: { beginAtZero: true } }
|
|
}
|
|
});
|
|
}
|
|
|
|
// Status Chart
|
|
if (document.getElementById('statusChart')) {
|
|
new Chart(document.getElementById('statusChart'), {
|
|
type: 'doughnut',
|
|
data: {
|
|
labels: <?= json_encode(array_map(function($s) { return __($s['status']); }, $orders_by_status)) ?>,
|
|
datasets: [{
|
|
data: <?= json_encode(array_column($orders_by_status, 'count')) ?>,
|
|
backgroundColor: ['#6c757d', '#3b82f6', '#10b981', '#111827', '#ef4444']
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: { legend: { position: 'bottom' } }
|
|
}
|
|
});
|
|
}
|
|
|
|
// Monthly Orders Chart
|
|
if (document.getElementById('monthlyOrdersChart')) {
|
|
new Chart(document.getElementById('monthlyOrdersChart'), {
|
|
type: 'bar',
|
|
data: {
|
|
labels: <?= json_encode(array_column($monthly_orders, 'month_year')) ?>,
|
|
datasets: [{
|
|
label: '<?= __('orders') ?>',
|
|
data: <?= json_encode(array_column($monthly_orders, 'count')) ?>,
|
|
backgroundColor: '#10b981',
|
|
borderRadius: 8
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: { legend: { display: false } },
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
stepSize: 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
<?php endif; ?>
|
|
|
|
<?php
|
|
require_once __DIR__ . '/includes/footer.php';
|
|
?>
|