diff --git a/admin_dashboard.php b/admin_dashboard.php
index a375d68..4a83d3f 100644
--- a/admin_dashboard.php
+++ b/admin_dashboard.php
@@ -1,333 +1,474 @@
query("SELECT COUNT(*) FROM inbound_mail")->fetchColumn() : 0;
-$total_outbound = canView('outbound') ? db()->query("SELECT COUNT(*) FROM outbound_mail")->fetchColumn() : 0;
-
-// Fetch statuses for badge and count
-$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
-
-$in_progress_id = null;
-foreach ($statuses_data as $id => $s) {
- if ($s['name'] == 'in_progress') {
- $in_progress_id = $id;
- break;
+// Helper functions for safe DB queries
+function getSafeCount($query, $params = []) {
+ try {
+ $stmt = db()->prepare($query);
+ $stmt->execute($params);
+ return $stmt->fetchColumn() ?: 0;
+ } catch (Exception $e) {
+ return 0;
}
}
+function getSafeValue($query, $params = []) {
+ try {
+ $stmt = db()->prepare($query);
+ $stmt->execute($params);
+ return $stmt->fetchColumn() ?: 0;
+ } catch (Exception $e) {
+ return 0;
+ }
+}
+
+// 1. Mail & Tasks
+$total_inbound = canView('inbound') ? getSafeCount("SELECT COUNT(*) FROM inbound_mail") : 0;
+$total_outbound = canView('outbound') ? getSafeCount("SELECT COUNT(*) FROM outbound_mail") : 0;
+$total_internal = canView('internal') ? getSafeCount("SELECT COUNT(*) FROM internal_mail") : 0;
+
$in_progress_count = 0;
-if ($in_progress_id) {
- if (canView('inbound')) {
- $stmt = db()->prepare("SELECT COUNT(*) FROM inbound_mail WHERE status_id = ?");
- $stmt->execute([$in_progress_id]);
- $in_progress_count += $stmt->fetchColumn();
- }
- if (canView('outbound')) {
- $stmt = db()->prepare("SELECT COUNT(*) FROM outbound_mail WHERE status_id = ?");
- $stmt->execute([$in_progress_id]);
- $in_progress_count += $stmt->fetchColumn();
- }
-}
-
-// My Assignments - Combine from all tables
-$my_assignments = [];
-$queries = [];
-if (canView('inbound')) {
- $queries[] = "SELECT id, 'inbound' as type, ref_no, subject, due_date, status_id, created_at FROM inbound_mail WHERE assigned_to = $user_id";
-}
-if (canView('outbound')) {
- $queries[] = "SELECT id, 'outbound' as type, ref_no, subject, due_date, status_id, created_at FROM outbound_mail WHERE assigned_to = $user_id";
-}
-if (canView('internal')) {
- $queries[] = "SELECT id, 'internal' as type, ref_no, subject, due_date, status_id, created_at FROM internal_mail WHERE assigned_to = $user_id";
-}
-
-if (!empty($queries)) {
- $full_query = "(" . implode(") UNION ALL (", $queries) . ") ORDER BY created_at DESC LIMIT 5";
- $stmt = db()->query($full_query);
- $my_assignments = $stmt->fetchAll();
-
- // Add status info to assignments
- foreach ($my_assignments as &$m) {
- $m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
- $m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
- }
-}
-
-// Recent Mail (Global for Admin/Clerk, otherwise limited)
-$recent_mail = [];
-$recent_queries = [];
-if (canView('inbound')) {
- $recent_queries[] = "SELECT m.id, 'inbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
- FROM inbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
-}
-if (canView('outbound')) {
- $recent_queries[] = "SELECT m.id, 'outbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
- FROM outbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
-}
-
-if (!empty($recent_queries)) {
- $full_recent_query = "(" . implode(") UNION ALL (", $recent_queries) . ")";
-
- if (!$is_admin && ($_SESSION['user_role'] ?? '') !== 'clerk') {
- $full_recent_query = "SELECT * FROM ($full_recent_query) AS combined WHERE assigned_to = $user_id OR created_by = $user_id ORDER BY created_at DESC LIMIT 10";
- } else {
- $full_recent_query = "SELECT * FROM ($full_recent_query) AS combined ORDER BY created_at DESC LIMIT 10";
+$overdue_count = 0;
+try {
+ $statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
+ $in_progress_id = null;
+ foreach ($statuses_data as $id => $s) {
+ if ($s['name'] == 'in_progress') {
+ $in_progress_id = $id;
+ break;
+ }
}
- $stmt = db()->query($full_recent_query);
- $recent_mail = $stmt->fetchAll();
-
- // Add status info
- foreach ($recent_mail as &$m) {
- $m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
- $m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
+ if ($in_progress_id) {
+ if (canView('inbound')) $in_progress_count += getSafeCount("SELECT COUNT(*) FROM inbound_mail WHERE status_id = ?", [$in_progress_id]);
+ if (canView('outbound')) $in_progress_count += getSafeCount("SELECT COUNT(*) FROM outbound_mail WHERE status_id = ?", [$in_progress_id]);
+ if (canView('internal')) $in_progress_count += getSafeCount("SELECT COUNT(*) FROM internal_mail WHERE status_id = ?", [$in_progress_id]);
}
-}
+
+ if (canView('reports')) {
+ $overdue_count += getSafeCount("SELECT COUNT(*) FROM inbound_mail WHERE due_date < CURDATE() AND status_id NOT IN (SELECT id FROM mailbox_statuses WHERE name IN ('closed', 'مكتمل', 'مؤرشف', 'مؤرشفة'))");
+ $overdue_count += getSafeCount("SELECT COUNT(*) FROM outbound_mail WHERE due_date < CURDATE() AND status_id NOT IN (SELECT id FROM mailbox_statuses WHERE name IN ('closed', 'مكتمل', 'مؤرشف', 'مؤرشفة'))");
+ $overdue_count += getSafeCount("SELECT COUNT(*) FROM internal_mail WHERE due_date < CURDATE() AND status_id NOT IN (SELECT id FROM mailbox_statuses WHERE name IN ('closed', 'مكتمل', 'مؤرشف', 'مؤرشفة'))");
+ }
+} catch (Exception $e) {}
-function getStatusBadge($mail) {
- $status_name = $mail['status_name'] ?? 'غير معروف';
- $status_color = $mail['status_color'] ?? '#6c757d';
-
- $display_name = $status_name;
- if ($status_name == 'received') $display_name = 'تم الاستلام';
- if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
- if ($status_name == 'closed') $display_name = 'مكتمل';
-
- return '' . htmlspecialchars($display_name ?? '') . '';
-}
+// 2. HR & Employees
+$total_employees = canView('hr_employees') ? getSafeCount("SELECT COUNT(*) FROM hr_employees") : 0;
+$pending_leaves = canView('hr_leaves') ? getSafeCount("SELECT COUNT(*) FROM hr_leaves WHERE status = 'pending'") : 0;
+$present_today = canView('hr_attendance') ? getSafeCount("SELECT COUNT(DISTINCT employee_id) FROM hr_attendance WHERE date = CURDATE() AND status = 'present'") : 0;
+
+// 3. Accounting & Expenses
+$total_expenses_month = canView('expenses') ? getSafeValue("SELECT SUM(amount) FROM expenses WHERE MONTH(date) = MONTH(CURRENT_DATE()) AND YEAR(date) = YEAR(CURRENT_DATE())") : 0;
+$total_accounts = canView('accounting') ? getSafeCount("SELECT COUNT(*) FROM accounting_accounts") : 0;
+
+// 4. Stock & Inventory
+$total_stock_items = canView('stock') ? getSafeCount("SELECT COUNT(*) FROM stock_items") : 0;
+$low_stock = canView('stock') ? getSafeCount("SELECT COUNT(*) FROM (SELECT si.id FROM stock_items si LEFT JOIN stock_quantities sq ON si.id = sq.item_id GROUP BY si.id, si.min_quantity HAVING COALESCE(SUM(sq.quantity), 0) <= si.min_quantity) AS t") : 0;
+
+// 5. Charity & Committees
+$total_charity_members = canView('charity_members') ? getSafeCount("SELECT COUNT(*) FROM charity_members") : 0;
+$total_committees = canView('committees') ? getSafeCount("SELECT COUNT(*) FROM committees") : 0;
+
+// 6. Events & Meetings
+$upcoming_meetings = canView('meetings') ? getSafeCount("SELECT COUNT(*) FROM meetings WHERE DATE(start_time) >= CURRENT_DATE() AND status != 'completed'") : 0;
+$upcoming_events = canView('events') ? getSafeCount("SELECT COUNT(*) FROM events WHERE event_date >= CURRENT_DATE()") : 0;
+
+// 7. Users
+$total_users = canView('users') ? getSafeCount("SELECT COUNT(*) FROM users") : 0;
?>
-
-
لوحة التحكم الإدارية
+
+
+
-query("SELECT COUNT(*) FROM inbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name NOT IN ('closed', 'مكتمل', 'مؤرشف', 'مؤرشفة'))")->fetchColumn();
- $overdue_count += db()->query("SELECT COUNT(*) FROM outbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name NOT IN ('closed', 'مكتمل', 'مؤرشف', 'مؤرشفة'))")->fetchColumn();
-
- if ($overdue_count > 0):
- ?>
-
-
-
-
-
- هناك = $overdue_count ?> مهام متأخرة تتطلب انتباهك!
-
-
عرض التقرير
+ 0): ?>
+
+
+
+
+
+ يوجد (= $overdue_count ?>) مهام أو مراسلات متأخرة تتطلب انتباهك!
+
عرض التقرير
-
+
+
-
+
+
+
+
المراسلات والمهام
+
+
-
-
-
-
البريد الوارد
- = $total_inbound ?>
-
-
+
-
-
-
-
البريد الصادر
- = $total_outbound ?>
-
-
+
-
+
-
-
-
-
قيد المعالجة
- = $in_progress_count ?>
-
-
+
+
+
+
+
+
+
+
+
+
الموارد البشرية (HR)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
المالية والمصروفات
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
المخزون والعهد
+
+
+
+
+
+
+
+
+
+
+
+
+
الإدارة والأنشطة
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
المستخدمين
- = db()->query("SELECT COUNT(*) FROM users")->fetchColumn() ?>
-
-
+
-
-
-
-
-
-
-
-
-
-
-
- |
- رقم القيد
- = $mail['ref_no'] ?>
- |
-
- الموضوع
- = htmlspecialchars($mail['subject'] ?? '') ?>
- |
-
- الموعد النهائي
-
-
- = $mail['due_date'] ?>
-
-
- -
-
- |
-
- الحالة
- = getStatusBadge($mail) ?>
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | رقم القيد |
- النوع |
- الموضوع |
- الموعد النهائي |
- المرسل/المستلم |
- المسؤول |
- الحالة |
- التاريخ |
-
-
-
-
-
- | = $mail['ref_no'] ?> |
-
-
- وارد
-
- صادر
-
- |
- = htmlspecialchars($mail['subject'] ?? '') ?> |
-
-
-
- = $mail['due_date'] ?>
-
-
- -
-
- |
- = htmlspecialchars($mail['sender'] ?: $mail['recipient']) ?> |
-
-
- = htmlspecialchars($mail['assigned_to_name'] ?? '') ?>
-
- غير معين
-
- |
- = getStatusBadge($mail) ?> |
- = date('Y-m-d', strtotime($mail['date_registered'])) ?> |
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+