Sindbad~EG File Manager
<?php
require_once 'config/config.php';
checkLogin();
$pageTitle = "Dashboard - " . APP_NAME;
// Get user stats
$db = Database::getInstance()->getConnection();
// Get access level filter
$accessFilter = applyAccessLevelFilter('m');
// Count members based on access level
$memberQuery = "SELECT COUNT(*) as count FROM members m WHERE 1=1" . $accessFilter['where'];
$stmt = $db->prepare($memberQuery);
$stmt->execute($accessFilter['params']);
$memberCount = $stmt->fetch()['count'];
// Count events based on access level
// Events table uses location_type and location_id instead of area_id/district_id/assembly_id
$eventQuery = "SELECT COUNT(*) as count FROM events e WHERE e.is_active = 1";
$eventParams = [];
if (!isSuperuser()) {
$accessLevel = getUserAccessLevel();
if ($accessLevel === 'assembly') {
$eventQuery .= " AND e.location_type = 'assembly' AND e.location_id = :location_id";
$eventParams['location_id'] = getUserAssemblyId();
} elseif ($accessLevel === 'district') {
$eventQuery .= " AND e.location_type IN ('district', 'assembly') AND e.location_id IN (
:location_id,
(SELECT id FROM assemblies WHERE district_id = :district_id)
)";
$eventParams['location_id'] = getUserDistrictId();
$eventParams['district_id'] = getUserDistrictId();
} elseif ($accessLevel === 'area') {
$eventQuery .= " AND e.location_type IN ('area', 'district', 'assembly')";
}
}
$stmt = $db->prepare($eventQuery);
$stmt->execute($eventParams);
$eventCount = $stmt->fetch()['count'];
// Count programs based on access level
$programQuery = "SELECT COUNT(*) as count FROM programs p WHERE 1=1" . getAccessLevelWhere('p');
$stmt = $db->prepare($programQuery);
$stmt->execute(getAccessLevelParams('p'));
$programCount = $stmt->fetch()['count'];
// Count ministries based on access level
$ministryQuery = "SELECT COUNT(*) as count FROM ministries m WHERE m.is_active = 1" . getAccessLevelWhere('m');
$stmt = $db->prepare($ministryQuery);
$stmt->execute(getAccessLevelParams('m'));
$ministryCount = $stmt->fetch()['count'];
// Get recent members with access filter
$recentMembersQuery = "SELECT m.*, d.district_name, a.assembly_name
FROM members m
LEFT JOIN districts d ON m.district_id = d.id
LEFT JOIN assemblies a ON m.assembly_id = a.id
WHERE 1=1" . getAccessLevelWhere('m') . "
ORDER BY m.created_at DESC LIMIT 5";
$stmt = $db->prepare($recentMembersQuery);
$stmt->execute(getAccessLevelParams('m'));
$recentMembers = $stmt->fetchAll();
// Get upcoming events with access filter
$upcomingEventsQuery = "SELECT e.* FROM events e
WHERE e.is_active = 1 AND e.start_date >= CURDATE()";
$upcomingEventsParams = [];
if (!isSuperuser()) {
$accessLevel = getUserAccessLevel();
if ($accessLevel === 'assembly') {
$upcomingEventsQuery .= " AND e.location_type = 'assembly' AND e.location_id = :location_id";
$upcomingEventsParams['location_id'] = getUserAssemblyId();
} elseif ($accessLevel === 'district') {
$upcomingEventsQuery .= " AND e.location_type IN ('district', 'assembly') AND (
(e.location_type = 'district' AND e.location_id = :district_id) OR
(e.location_type = 'assembly' AND e.location_id IN (SELECT id FROM assemblies WHERE district_id = :district_id2))
)";
$upcomingEventsParams['district_id'] = getUserDistrictId();
$upcomingEventsParams['district_id2'] = getUserDistrictId();
} elseif ($accessLevel === 'area') {
$upcomingEventsQuery .= " AND e.location_type IN ('area', 'district', 'assembly')";
}
}
$upcomingEventsQuery .= " ORDER BY e.start_date ASC LIMIT 5";
$stmt = $db->prepare($upcomingEventsQuery);
$stmt->execute($upcomingEventsParams);
$upcomingEvents = $stmt->fetchAll();
// Get modules based on access level
if (isSuperuser()) {
$moduleStmt = $db->prepare("SELECT * FROM module_management WHERE is_active = 1 ORDER BY display_order");
$moduleStmt->execute();
} else {
$moduleStmt = $db->prepare("
SELECT * FROM module_management
WHERE is_active = 1
AND required_role IN ('assembly', 'district', 'area')
ORDER BY display_order
");
$moduleStmt->execute();
}
$modules = $moduleStmt->fetchAll();
// Get recent notifications
$notification = new Notification();
$recentNotifications = $notification->getUserNotifications($_SESSION['user_id'], false, 5);
include 'includes/header.php';
?>
<?php include 'includes/sidebar.php'; ?>
<!-- Main Content -->
<main class="flex-1 md:ml-64 mt-16">
<div class="container mx-auto px-4 py-8">
<!-- Access Level Badge -->
<div class="mb-6">
<?php echo getUserAccessBadge(); ?>
</div>
<?php if (isset($_SESSION['error'])): ?>
<div class="mb-6 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg shadow-md" role="alert">
<div class="flex items-center">
<i class="fas fa-exclamation-circle mr-3 text-xl"></i>
<div>
<p class="font-bold">Access Denied</p>
<p><?php echo htmlspecialchars($_SESSION['error']); ?></p>
</div>
</div>
</div>
<?php unset($_SESSION['error']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['success'])): ?>
<div class="mb-6 bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg shadow-md" role="alert">
<div class="flex items-center">
<i class="fas fa-check-circle mr-3 text-xl"></i>
<p><?php echo htmlspecialchars($_SESSION['success']); ?></p>
</div>
</div>
<?php unset($_SESSION['success']); ?>
<?php endif; ?>
<!-- Welcome Section -->
<div class="mb-8">
<div class="rounded-2xl shadow-xl p-8 text-white" style="background: linear-gradient(135deg, #1E40AF 0%, #9333EA 50%, #F97316 100%);">
<div class="flex flex-col md:flex-row items-center justify-between">
<div class="mb-4 md:mb-0">
<h1 class="text-3xl md:text-4xl font-bold mb-2">
Welcome back, <?php echo htmlspecialchars(getCurrentUserName()); ?>! 👋
</h1>
<p class="text-white/90 text-lg">
<?php
$hour = date('H');
if ($hour < 12) echo "Good Morning";
elseif ($hour < 18) echo "Good Afternoon";
else echo "Good Evening";
?>! Here's what's happening today.
</p>
</div>
<div class="text-center">
<div class="text-5xl font-bold"><?php echo date('d'); ?></div>
<div class="text-lg"><?php echo date('F Y'); ?></div>
</div>
</div>
</div>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Total Members -->
<div class="bg-white rounded-xl shadow-lg p-6 card-hover transition transform hover:scale-105" style="border-left: 4px solid #1E40AF;">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm font-medium mb-1">Total Members</p>
<h3 class="text-3xl font-bold text-gray-800"><?php echo number_format($memberCount); ?></h3>
<p class="text-green-500 text-sm mt-2">
<i class="fas fa-arrow-up"></i> Active
</p>
</div>
<div class="rounded-full p-4" style="background: linear-gradient(135deg, #1E40AF 0%, #9333EA 100%);">
<i class="fas fa-users text-3xl text-white"></i>
</div>
</div>
</div>
<!-- Events -->
<div class="bg-white rounded-xl shadow-lg p-6 card-hover transition transform hover:scale-105" style="border-left: 4px solid #F97316;">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm font-medium mb-1">Total Events</p>
<h3 class="text-3xl font-bold text-gray-800"><?php echo number_format($eventCount); ?></h3>
<p class="text-blue-500 text-sm mt-2">
<i class="fas fa-calendar"></i> All Events
</p>
</div>
<div class="rounded-full p-4" style="background: linear-gradient(135deg, #F97316 0%, #FBBF24 100%);">
<i class="fas fa-calendar-alt text-3xl text-white"></i>
</div>
</div>
</div>
<!-- Programs -->
<div class="bg-white rounded-xl shadow-lg p-6 card-hover border-l-4 border-green-500">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm font-medium mb-1">Total Programs</p>
<h3 class="text-3xl font-bold text-gray-800"><?php echo number_format($programCount); ?></h3>
<p class="text-green-500 text-sm mt-2">
<i class="fas fa-check-circle"></i> Active
</p>
</div>
<div class="bg-green-100 rounded-full p-4">
<i class="fas fa-list-check text-3xl text-green-500"></i>
</div>
</div>
</div>
<!-- Notifications -->
<div class="bg-white rounded-xl shadow-lg p-6 card-hover border-l-4 border-purple-500">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm font-medium mb-1">Notifications</p>
<h3 class="text-3xl font-bold text-gray-800">
<?php echo $notification->getUnreadCount($_SESSION['user_id']); ?>
</h3>
<p class="text-purple-500 text-sm mt-2">Unread</p>
</div>
<div class="bg-purple-100 rounded-full p-4">
<i class="fas fa-bell text-3xl text-purple-500"></i>
</div>
</div>
</div>
</div>
<!-- Quick Access Modules -->
<div class="mb-8">
<h2 class="text-2xl font-bold text-gray-800 mb-6">
<i class="fas fa-th-large mr-2 text-blue-500"></i>Quick Access
</h2>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
<?php foreach ($modules as $module): ?>
<a href="<?php echo BASE_URL . ($module['module_url'] ?? '#'); ?>"
class="bg-white rounded-xl shadow-lg p-6 text-center card-hover group">
<div class="inline-block p-4 bg-gradient-to-br from-blue-100 to-yellow-100 rounded-full mb-3 group-hover:scale-110 transition">
<i class="fas fa-<?php echo htmlspecialchars($module['module_icon'] ?? 'circle'); ?> text-3xl text-blue-600"></i>
</div>
<h3 class="font-semibold text-gray-800 text-sm"><?php echo htmlspecialchars($module['module_name'] ?? 'Module'); ?></h3>
</a>
<?php endforeach; ?>
</div>
</div>
<!-- Live QR Attendance Widget -->
<div class="mb-8">
<div class="bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 rounded-xl shadow-2xl p-8 text-white">
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-3xl font-bold mb-2">
<i class="fas fa-qrcode mr-3"></i>Live QR Attendance
</h2>
<p class="text-blue-100 text-lg">Real-time attendance tracking via QR code scanning</p>
</div>
<div class="hidden md:block">
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-xl p-6">
<i class="fas fa-mobile-alt text-6xl opacity-80"></i>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<?php
// Get today's QR attendance stats
$qrStatsStmt = $db->prepare("
SELECT
COUNT(DISTINCT pa.member_id) as checked_in_today,
COUNT(DISTINCT pa.program_id) as active_programs
FROM program_attendance pa
WHERE pa.attendance_date = :date
");
$qrStatsStmt->execute(['date' => date('Y-m-d')]);
$qrStats = $qrStatsStmt->fetch();
?>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-blue-100 mb-1">Today's Check-Ins</p>
<p class="text-3xl font-bold"><?php echo $qrStats['checked_in_today'] ?? 0; ?></p>
</div>
<i class="fas fa-user-check text-3xl opacity-70"></i>
</div>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-blue-100 mb-1">Active Programs</p>
<p class="text-3xl font-bold"><?php echo $qrStats['active_programs'] ?? 0; ?></p>
</div>
<i class="fas fa-calendar text-3xl opacity-70"></i>
</div>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-blue-100 mb-1">Status</p>
<p class="text-2xl font-bold">
<i class="fas fa-circle text-green-400 text-sm mr-2"></i>Live
</p>
</div>
<i class="fas fa-broadcast-tower text-3xl opacity-70"></i>
</div>
</div>
</div>
<div class="flex gap-4">
<a href="<?php echo BASE_URL; ?>modules/attendance/live-qr.php"
class="flex-1 bg-white text-blue-600 px-6 py-4 rounded-lg font-semibold hover:bg-blue-50 transition text-center shadow-lg">
<i class="fas fa-qrcode mr-2"></i>Open Scanner
</a>
<a href="<?php echo BASE_URL; ?>modules/programs/index.php"
class="flex-1 bg-white bg-opacity-20 backdrop-blur-sm border-2 border-white px-6 py-4 rounded-lg font-semibold hover:bg-opacity-30 transition text-center">
<i class="fas fa-list mr-2"></i>View Programs
</a>
</div>
</div>
</div>
<!-- Recent Activity & Notifications -->
<!-- AI Chatbot Feature Card (Superuser Only) -->
<?php if (isSuperuser()): ?>
<div class="mb-8">
<div class="bg-gradient-to-r from-blue-600 via-purple-600 to-pink-600 rounded-xl shadow-2xl p-8 text-white">
<div class="flex flex-col md:flex-row items-center justify-between">
<div class="flex items-center gap-4 mb-4 md:mb-0">
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-2xl p-4">
<i class="fas fa-robot text-5xl"></i>
</div>
<div>
<h2 class="text-3xl font-bold mb-2">
AI Chatbot Management
</h2>
<p class="text-blue-100 text-lg">Manage FAQs, documents, and intelligent responses</p>
</div>
</div>
<a href="<?php echo BASE_URL; ?>modules/chatbot/index.php"
class="bg-white text-purple-600 px-8 py-3 rounded-lg font-bold hover:bg-blue-50 transition-all duration-300 shadow-lg inline-flex items-center">
<i class="fas fa-cog mr-2"></i>
Manage Chatbot
</a>
</div>
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mt-6">
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<p class="text-sm text-blue-100 mb-1">FAQs</p>
<p class="text-2xl font-bold">
<?php
try {
$faqCount = $db->query("SELECT COUNT(*) FROM chatbot_faqs WHERE is_active = 1")->fetchColumn();
echo $faqCount ?? 0;
} catch (Exception $e) {
echo '0';
}
?>
</p>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<p class="text-sm text-blue-100 mb-1">Documents</p>
<p class="text-2xl font-bold">
<?php
try {
$docCount = $db->query("SELECT COUNT(*) FROM chatbot_documents WHERE is_active = 1")->fetchColumn();
echo $docCount ?? 0;
} catch (Exception $e) {
echo '0';
}
?>
</p>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<p class="text-sm text-blue-100 mb-1">Conversations</p>
<p class="text-2xl font-bold">
<?php
try {
$convCount = $db->query("SELECT COUNT(*) FROM chatbot_conversations")->fetchColumn();
echo $convCount ?? 0;
} catch (Exception $e) {
echo '0';
}
?>
</p>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-lg p-4">
<p class="text-sm text-blue-100 mb-1">Status</p>
<p class="text-2xl font-bold">
<?php
try {
$enabled = $db->query("SELECT setting_value FROM chatbot_settings WHERE setting_key = 'enabled'")->fetchColumn();
echo $enabled ? '🟢 Active' : '🔴 Inactive';
} catch (Exception $e) {
echo '⚪ N/A';
}
?>
</p>
</div>
</div>
</div>
</div>
<?php endif; ?>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Recent Members -->
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-bold text-gray-800">
<i class="fas fa-users mr-2 text-blue-500"></i>Recent Members
</h3>
<a href="<?php echo BASE_URL; ?>modules/membership/index.php" class="text-blue-500 hover:text-blue-600 text-sm">
View All <i class="fas fa-arrow-right ml-1"></i>
</a>
</div>
<div class="space-y-3">
<?php if (empty($recentMembers)):
?>
<div class="text-center py-8 text-gray-500">
<i class="fas fa-users text-4xl mb-2"></i>
<p>No members yet</p>
</div>
<?php else: ?>
<?php foreach ($recentMembers as $member): ?>
<div class="flex items-center space-x-3 p-3 hover:bg-gray-50 rounded-lg transition">
<img src="<?php echo !empty($member['profile_photo']) ? BASE_URL . 'uploads/members/' . $member['profile_photo'] : BASE_URL . 'assets/images/default-avatar.png'; ?>"
alt="<?php echo htmlspecialchars($member['first_name'] ?? ''); ?>"
class="w-12 h-12 rounded-full object-cover border-2 border-blue-200">
<div class="flex-1">
<h4 class="font-semibold text-gray-800">
<?php echo htmlspecialchars(($member['first_name'] ?? '') . ' ' . ($member['last_name'] ?? '')); ?>
</h4>
<p class="text-sm text-gray-500"><?php echo htmlspecialchars($member['membershipcard_id'] ?? 'N/A'); ?></p>
</div>
<span class="text-xs text-gray-400"><?php echo timeAgo($member['created_at']); ?></span>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<!-- Recent Notifications -->
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-bold text-gray-800">
<i class="fas fa-bell mr-2 text-yellow-500"></i>Recent Notifications
</h3>
<a href="<?php echo BASE_URL; ?>modules/notifications/index.php" class="text-blue-500 hover:text-blue-600 text-sm">
View All <i class="fas fa-arrow-right ml-1"></i>
</a>
</div>
<div class="space-y-3">
<?php if (empty($recentNotifications)): ?>
<div class="text-center py-8 text-gray-500">
<i class="fas fa-bell-slash text-4xl mb-2"></i>
<p>No notifications</p>
</div>
<?php else: ?>
<?php foreach ($recentNotifications as $notif): ?>
<div class="flex items-start space-x-3 p-3 hover:bg-gray-50 rounded-lg transition <?php echo ($notif['is_read'] ?? false) ? 'opacity-60' : ''; ?>">
<div class="flex-shrink-0 mt-1">
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center">
<i class="fas fa-info-circle text-blue-500"></i>
</div>
</div>
<div class="flex-1">
<h4 class="font-semibold text-sm text-gray-800"><?php echo htmlspecialchars($notif['title'] ?? ''); ?></h4>
<p class="text-xs text-gray-600 mt-1"><?php echo htmlspecialchars($notif['message'] ?? ''); ?></p>
<span class="text-xs text-gray-400 mt-1 block"><?php echo timeAgo($notif['created_at'] ?? ''); ?></span>
</div>
<?php if (!($notif['is_read'] ?? false)): ?>
<div class="w-2 h-2 bg-blue-500 rounded-full flex-shrink-0 mt-2"></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists