Sindbad~EG File Manager
<?php
session_start();
require_once '../includes/functions.php';
// Check if user is logged in and has admin privileges
if (!isLoggedIn() || (!hasRole('superuser') && !hasRole('area_admin'))) {
header('Location: ../login.php');
exit;
}
$db = new CopMadinaDB();
$conn = $db->getConnection();
$user = getCurrentUser();
// Get filter parameters
$status_filter = $_GET['status'] ?? '';
$type_filter = $_GET['type'] ?? '';
$date_filter = $_GET['date'] ?? '';
$search = $_GET['search'] ?? '';
$page = max(1, (int)($_GET['page'] ?? 1));
$per_page = 20;
$offset = ($page - 1) * $per_page;
// Build query conditions
$conditions = [];
$params = [];
if ($status_filter) {
$conditions[] = "status = ?";
$params[] = $status_filter;
}
if ($type_filter) {
$conditions[] = "email_type = ?";
$params[] = $type_filter;
}
if ($date_filter) {
$conditions[] = "DATE(created_at) = ?";
$params[] = $date_filter;
}
if ($search) {
$conditions[] = "(recipient_email LIKE ? OR recipient_name LIKE ? OR subject LIKE ?)";
$search_param = "%{$search}%";
$params[] = $search_param;
$params[] = $search_param;
$params[] = $search_param;
}
$where_clause = $conditions ? 'WHERE ' . implode(' AND ', $conditions) : '';
// Get total count
$count_query = "SELECT COUNT(*) as total FROM email_logs {$where_clause}";
$stmt = $conn->prepare($count_query);
$stmt->execute($params);
$total_records = $stmt->fetch()['total'];
$total_pages = ceil($total_records / $per_page);
// Get email logs
$query = "
SELECT * FROM email_logs
{$where_clause}
ORDER BY created_at DESC
LIMIT {$per_page} OFFSET {$offset}
";
$stmt = $conn->prepare($query);
$stmt->execute($params);
$email_logs = $stmt->fetchAll();
// Get statistics
$stats_query = "
SELECT
COUNT(*) as total,
SUM(CASE WHEN status = 'sent' THEN 1 ELSE 0 END) as sent,
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
SUM(CASE WHEN DATE(created_at) = CURDATE() THEN 1 ELSE 0 END) as today
FROM email_logs
";
$stmt = $conn->prepare($stats_query);
$stmt->execute();
$stats = $stmt->fetch();
$settings = getSettings();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Logs - COP Madina Admin</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-gradient-to-br from-slate-50 to-blue-50 min-h-screen">
<div id="app">
<?php include 'includes/admin_sidebar.php'; ?>
<!-- Main Content -->
<main class="ml-72 min-h-screen">
<!-- Header -->
<header class="bg-white/80 backdrop-blur-sm border-b border-slate-200/50 sticky top-0 z-30">
<div class="px-8 py-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-slate-800">Email Logs</h1>
<p class="text-slate-600 mt-1">Monitor all email activity and delivery status</p>
</div>
<div class="flex items-center space-x-4">
<a href="email-settings.php"
class="bg-gradient-to-r from-blue-500 via-slate-600 to-violet-400 text-white px-4 py-2 rounded-lg font-medium hover:shadow-lg transition-all duration-200 flex items-center space-x-2">
<i class="fas fa-cog"></i>
<span>Email Settings</span>
</a>
</div>
</div>
</div>
</header>
<div class="p-8">
<!-- Statistics Cards -->
<div class="grid grid-cols-1 md:grid-cols-5 gap-6 mb-8">
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-slate-600">Total Emails</p>
<p class="text-2xl font-bold text-slate-800"><?php echo number_format($stats['total']); ?></p>
</div>
<div class="p-3 bg-blue-100 rounded-lg">
<i class="fas fa-envelope text-blue-600"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-slate-600">Sent</p>
<p class="text-2xl font-bold text-green-600"><?php echo number_format($stats['sent']); ?></p>
</div>
<div class="p-3 bg-green-100 rounded-lg">
<i class="fas fa-check-circle text-green-600"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-slate-600">Failed</p>
<p class="text-2xl font-bold text-red-600"><?php echo number_format($stats['failed']); ?></p>
</div>
<div class="p-3 bg-red-100 rounded-lg">
<i class="fas fa-times-circle text-red-600"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-slate-600">Pending</p>
<p class="text-2xl font-bold text-yellow-600"><?php echo number_format($stats['pending']); ?></p>
</div>
<div class="p-3 bg-yellow-100 rounded-lg">
<i class="fas fa-clock text-yellow-600"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-slate-600">Today</p>
<p class="text-2xl font-bold text-purple-600"><?php echo number_format($stats['today']); ?></p>
</div>
<div class="p-3 bg-purple-100 rounded-lg">
<i class="fas fa-calendar-day text-purple-600"></i>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 p-6 mb-8">
<form method="GET" class="grid grid-cols-1 md:grid-cols-5 gap-4">
<div>
<label for="search" class="block text-sm font-medium text-slate-700 mb-2">Search</label>
<input type="text" id="search" name="search"
class="w-full px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Email, name, or subject..."
value="<?php echo htmlspecialchars($search); ?>">
</div>
<div>
<label for="status" class="block text-sm font-medium text-slate-700 mb-2">Status</label>
<select id="status" name="status"
class="w-full px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">All Statuses</option>
<option value="sent" <?php echo $status_filter === 'sent' ? 'selected' : ''; ?>>Sent</option>
<option value="failed" <?php echo $status_filter === 'failed' ? 'selected' : ''; ?>>Failed</option>
<option value="pending" <?php echo $status_filter === 'pending' ? 'selected' : ''; ?>>Pending</option>
</select>
</div>
<div>
<label for="type" class="block text-sm font-medium text-slate-700 mb-2">Type</label>
<select id="type" name="type"
class="w-full px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">All Types</option>
<option value="welcome" <?php echo $type_filter === 'welcome' ? 'selected' : ''; ?>>Welcome</option>
<option value="test" <?php echo $type_filter === 'test' ? 'selected' : ''; ?>>Test</option>
<option value="notification" <?php echo $type_filter === 'notification' ? 'selected' : ''; ?>>Notification</option>
</select>
</div>
<div>
<label for="date" class="block text-sm font-medium text-slate-700 mb-2">Date</label>
<input type="date" id="date" name="date"
class="w-full px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
value="<?php echo htmlspecialchars($date_filter); ?>">
</div>
<div class="flex items-end space-x-2">
<button type="submit"
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors flex items-center space-x-2">
<i class="fas fa-search"></i>
<span>Filter</span>
</button>
<a href="email-logs.php"
class="bg-slate-500 text-white px-4 py-2 rounded-lg hover:bg-slate-600 transition-colors">
<i class="fas fa-times"></i>
</a>
</div>
</form>
</div>
<!-- Email Logs Table -->
<div class="bg-white rounded-xl shadow-sm border border-slate-200/50 overflow-hidden">
<div class="p-6 border-b border-slate-200/50">
<h2 class="text-xl font-semibold text-slate-800">Email Logs</h2>
<p class="text-slate-600 text-sm mt-1">
Showing <?php echo count($email_logs); ?> of <?php echo number_format($total_records); ?> emails
</p>
</div>
<?php if (empty($email_logs)): ?>
<div class="p-12 text-center">
<i class="fas fa-inbox text-6xl text-slate-300 mb-4"></i>
<h3 class="text-xl font-semibold text-slate-600 mb-2">No Email Logs Found</h3>
<p class="text-slate-500">No emails match your current filters.</p>
</div>
<?php else: ?>
<div class="overflow-x-auto">
<table class="w-full">
<thead class="bg-slate-50 border-b border-slate-200">
<tr>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Recipient</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Subject</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Type</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Status</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Date</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-200">
<?php foreach ($email_logs as $log): ?>
<tr class="hover:bg-slate-50 transition-colors">
<td class="px-6 py-4">
<div>
<div class="font-medium text-slate-800">
<?php echo htmlspecialchars($log['recipient_name'] ?: 'Unknown'); ?>
</div>
<div class="text-sm text-slate-500">
<?php echo htmlspecialchars($log['recipient_email']); ?>
</div>
</div>
</td>
<td class="px-6 py-4">
<div class="text-sm text-slate-800 max-w-xs truncate">
<?php echo htmlspecialchars($log['subject']); ?>
</div>
</td>
<td class="px-6 py-4">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
<?php
switch($log['email_type']) {
case 'welcome': echo 'bg-blue-100 text-blue-800'; break;
case 'test': echo 'bg-purple-100 text-purple-800'; break;
case 'notification': echo 'bg-green-100 text-green-800'; break;
default: echo 'bg-slate-100 text-slate-800';
}
?>">
<?php echo ucfirst($log['email_type']); ?>
</span>
</td>
<td class="px-6 py-4">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
<?php
switch($log['status']) {
case 'sent': echo 'bg-green-100 text-green-800'; break;
case 'failed': echo 'bg-red-100 text-red-800'; break;
case 'pending': echo 'bg-yellow-100 text-yellow-800'; break;
default: echo 'bg-slate-100 text-slate-800';
}
?>">
<i class="fas <?php
switch($log['status']) {
case 'sent': echo 'fa-check-circle'; break;
case 'failed': echo 'fa-times-circle'; break;
case 'pending': echo 'fa-clock'; break;
default: echo 'fa-question-circle';
}
?> mr-1"></i>
<?php echo ucfirst($log['status']); ?>
</span>
</td>
<td class="px-6 py-4 text-sm text-slate-500">
<div><?php echo date('M j, Y', strtotime($log['created_at'])); ?></div>
<div><?php echo date('g:i A', strtotime($log['created_at'])); ?></div>
</td>
<td class="px-6 py-4">
<button @click="viewEmail(<?php echo htmlspecialchars(json_encode($log)); ?>)"
class="text-blue-600 hover:text-blue-700 font-medium text-sm">
<i class="fas fa-eye mr-1"></i>View
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- Pagination -->
<?php if ($total_pages > 1): ?>
<div class="px-6 py-4 border-t border-slate-200 flex items-center justify-between">
<div class="text-sm text-slate-500">
Showing <?php echo (($page - 1) * $per_page) + 1; ?> to <?php echo min($page * $per_page, $total_records); ?> of <?php echo number_format($total_records); ?> results
</div>
<div class="flex space-x-2">
<?php if ($page > 1): ?>
<a href="?<?php echo http_build_query(array_merge($_GET, ['page' => $page - 1])); ?>"
class="px-3 py-2 border border-slate-300 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-50">
Previous
</a>
<?php endif; ?>
<?php for ($i = max(1, $page - 2); $i <= min($total_pages, $page + 2); $i++): ?>
<a href="?<?php echo http_build_query(array_merge($_GET, ['page' => $i])); ?>"
class="px-3 py-2 border rounded-lg text-sm font-medium <?php echo $i === $page ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 text-slate-700 hover:bg-slate-50'; ?>">
<?php echo $i; ?>
</a>
<?php endfor; ?>
<?php if ($page < $total_pages): ?>
<a href="?<?php echo http_build_query(array_merge($_GET, ['page' => $page + 1])); ?>"
class="px-3 py-2 border border-slate-300 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-50">
Next
</a>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
</main>
<!-- Email View Modal -->
<div v-if="selectedEmail" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4" @click="closeModal">
<div class="bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden" @click.stop>
<div class="p-6 border-b border-slate-200 flex items-center justify-between">
<h3 class="text-xl font-semibold text-slate-800">Email Details</h3>
<button @click="closeModal" class="text-slate-400 hover:text-slate-600">
<i class="fas fa-times text-xl"></i>
</button>
</div>
<div class="p-6 overflow-y-auto max-h-[calc(90vh-120px)]">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div>
<label class="block text-sm font-medium text-slate-700 mb-1">Recipient</label>
<div class="text-slate-800">{{ selectedEmail.recipient_name || 'Unknown' }}</div>
<div class="text-sm text-slate-500">{{ selectedEmail.recipient_email }}</div>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 mb-1">Status</label>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium"
:class="getStatusClass(selectedEmail.status)">
<i :class="getStatusIcon(selectedEmail.status)" class="mr-1"></i>
{{ selectedEmail.status.charAt(0).toUpperCase() + selectedEmail.status.slice(1) }}
</span>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 mb-1">Type</label>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
{{ selectedEmail.email_type.charAt(0).toUpperCase() + selectedEmail.email_type.slice(1) }}
</span>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 mb-1">Date</label>
<div class="text-slate-800">{{ formatDate(selectedEmail.created_at) }}</div>
</div>
</div>
<div class="mb-6">
<label class="block text-sm font-medium text-slate-700 mb-2">Subject</label>
<div class="bg-slate-50 p-4 rounded-lg text-slate-800">
{{ selectedEmail.subject }}
</div>
</div>
<div class="mb-6">
<label class="block text-sm font-medium text-slate-700 mb-2">Email Body</label>
<div class="bg-slate-50 p-4 rounded-lg text-slate-800 whitespace-pre-wrap max-h-96 overflow-y-auto">
{{ selectedEmail.body }}
</div>
</div>
<div v-if="selectedEmail.error_message" class="mb-6">
<label class="block text-sm font-medium text-slate-700 mb-2">Error Message</label>
<div class="bg-red-50 border border-red-200 p-4 rounded-lg text-red-800">
{{ selectedEmail.error_message }}
</div>
</div>
</div>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
selectedEmail: null
}
},
methods: {
viewEmail(email) {
this.selectedEmail = email;
},
closeModal() {
this.selectedEmail = null;
},
getStatusClass(status) {
switch(status) {
case 'sent': return 'bg-green-100 text-green-800';
case 'failed': return 'bg-red-100 text-red-800';
case 'pending': return 'bg-yellow-100 text-yellow-800';
default: return 'bg-slate-100 text-slate-800';
}
},
getStatusIcon(status) {
switch(status) {
case 'sent': return 'fas fa-check-circle';
case 'failed': return 'fas fa-times-circle';
case 'pending': return 'fas fa-clock';
default: return 'fas fa-question-circle';
}
},
formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
}
}).mount('#app');
</script>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists