Sindbad~EG File Manager
<?php
require_once '../../config/config.php';
checkLogin();
$pageTitle = "Events Management - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$success = '';
$error = '';
// Get user access information
$accessLevel = $_SESSION['access_level'] ?? 'assembly';
$userAreaId = $_SESSION['area_id'] ?? null;
$userDistrictId = $_SESSION['district_id'] ?? null;
$userAssemblyId = $_SESSION['assembly_id'] ?? null;
// Handle form submission for adding/editing events
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$eventId = $_POST['event_id'] ?? null;
$name = sanitize($_POST['name']);
$description = sanitize($_POST['description']);
$startDate = $_POST['start_date'] ?: null;
$endDate = $_POST['end_date'] ?: null;
$locationId = $_POST['location_id'] ?: null;
$locationType = $_POST['location_type'];
$registrationStatus = $_POST['registration_status'];
$registrationOpenDate = $_POST['registration_open_date'] ?: null;
$registrationCloseDate = $_POST['registration_close_date'] ?: null;
$registrationMessage = sanitize($_POST['registration_message']);
$isActive = isset($_POST['is_active']) ? 1 : 0;
if (empty($name)) {
throw new Exception("Event name is required");
}
if ($eventId) {
// Update existing event
$stmt = $db->prepare("
UPDATE events SET
name = :name,
description = :description,
start_date = :start_date,
end_date = :end_date,
location_id = :location_id,
location_type = :location_type,
registration_status = :registration_status,
registration_open_date = :registration_open_date,
registration_close_date = :registration_close_date,
registration_message = :registration_message,
is_active = :is_active
WHERE id = :id
");
$stmt->execute([
'name' => $name,
'description' => $description,
'start_date' => $startDate,
'end_date' => $endDate,
'location_id' => $locationId,
'location_type' => $locationType,
'registration_status' => $registrationStatus,
'registration_open_date' => $registrationOpenDate,
'registration_close_date' => $registrationCloseDate,
'registration_message' => $registrationMessage,
'is_active' => $isActive,
'id' => $eventId
]);
$success = "Event updated successfully!";
} else {
// Create new event
$stmt = $db->prepare("
INSERT INTO events (
name, description, start_date, end_date, location_id, location_type,
registration_status, registration_open_date, registration_close_date,
registration_message, is_active, created_by
) VALUES (
:name, :description, :start_date, :end_date, :location_id, :location_type,
:registration_status, :registration_open_date, :registration_close_date,
:registration_message, :is_active, :created_by
)
");
$stmt->execute([
'name' => $name,
'description' => $description,
'start_date' => $startDate,
'end_date' => $endDate,
'location_id' => $locationId,
'location_type' => $locationType,
'registration_status' => $registrationStatus,
'registration_open_date' => $registrationOpenDate,
'registration_close_date' => $registrationCloseDate,
'registration_message' => $registrationMessage,
'is_active' => $isActive,
'created_by' => $_SESSION['user_id']
]);
$success = "Event created successfully!";
}
// Log the action
$auditLog = new AuditLog();
$auditLog->log($_SESSION['user_id'], $eventId ? 'update' : 'create', 'events', $eventId ?: $db->lastInsertId());
} catch (Exception $e) {
$error = "Error: " . $e->getMessage();
}
}
// Handle delete request
if (isset($_GET['delete']) && !empty($_GET['delete'])) {
try {
$eventId = (int)$_GET['delete'];
// Check if event has associated codes
$stmt = $db->prepare("SELECT COUNT(*) as count FROM memberuser_codes WHERE event_id = :event_id");
$stmt->execute(['event_id' => $eventId]);
$codeCount = $stmt->fetch()['count'];
if ($codeCount > 0) {
$error = "Cannot delete event. It has {$codeCount} associated member/user codes.";
} else {
$stmt = $db->prepare("DELETE FROM events WHERE id = :id");
$stmt->execute(['id' => $eventId]);
$auditLog = new AuditLog();
$auditLog->log($_SESSION['user_id'], 'delete', 'events', $eventId);
$success = "Event deleted successfully!";
}
} catch (Exception $e) {
$error = "Error deleting event: " . $e->getMessage();
}
}
// Get events based on access level
$eventsQuery = "
SELECT e.*, u.full_name as created_by_name,
CASE
WHEN e.location_type = 'area' THEN a.area_name
WHEN e.location_type = 'district' THEN d.district_name
WHEN e.location_type = 'assembly' THEN asm.assembly_name
ELSE 'General'
END as location_name
FROM events e
LEFT JOIN users u ON e.created_by = u.id
LEFT JOIN areas a ON e.location_id = a.id AND e.location_type = 'area'
LEFT JOIN districts d ON e.location_id = d.id AND e.location_type = 'district'
LEFT JOIN assemblies asm ON e.location_id = asm.id AND e.location_type = 'assembly'
WHERE 1=1
";
$params = [];
// Filter based on user access level
if ($accessLevel === 'assembly') {
$eventsQuery .= " AND ((e.location_type = 'assembly' AND e.location_id = :assembly_id) OR e.location_id IS NULL)";
$params['assembly_id'] = $userAssemblyId;
} elseif ($accessLevel === 'district') {
$eventsQuery .= " AND ((e.location_type IN ('district', 'assembly') AND (e.location_id = :district_id OR e.location_id IN (SELECT id FROM assemblies WHERE district_id = :district_id2))) OR e.location_id IS NULL)";
$params['district_id'] = $userDistrictId;
$params['district_id2'] = $userDistrictId;
} elseif ($accessLevel === 'area') {
$eventsQuery .= " AND ((e.location_type IN ('area', 'district', 'assembly') AND (e.location_id = :area_id OR e.location_id IN (SELECT id FROM districts WHERE area_id = :area_id2) OR e.location_id IN (SELECT id FROM assemblies WHERE district_id IN (SELECT id FROM districts WHERE area_id = :area_id3)))) OR e.location_id IS NULL)";
$params['area_id'] = $userAreaId;
$params['area_id2'] = $userAreaId;
$params['area_id3'] = $userAreaId;
}
$eventsQuery .= " ORDER BY e.created_at DESC";
$stmt = $db->prepare($eventsQuery);
$stmt->execute($params);
$events = $stmt->fetchAll();
// Get locations based on access level
$areas = [];
$districts = [];
$assemblies = [];
if ($accessLevel === 'superuser' || $accessLevel === 'area') {
$areasQuery = "SELECT * FROM areas WHERE is_active = 1";
if ($accessLevel === 'area') {
$areasQuery .= " AND id = $userAreaId";
}
$areas = $db->query($areasQuery)->fetchAll();
}
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">
<div class="max-w-7xl mx-auto">
<!-- Header -->
<div class="flex justify-between items-center mb-6">
<div>
<h1 class="text-3xl font-bold text-gray-800">
<i class="fas fa-calendar-alt mr-2 text-blue-500"></i>Events Management
</h1>
<p class="text-gray-600 mt-2">Manage church events and activities</p>
</div>
<button onclick="openEventModal()"
class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition">
<i class="fas fa-plus mr-2"></i>Add Event
</button>
</div>
<!-- Success/Error Messages -->
<?php if (!empty($success)): ?>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-6 flex items-center">
<i class="fas fa-check-circle mr-2"></i>
<span><?php echo $success; ?></span>
</div>
<?php endif; ?>
<?php if (!empty($error)): ?>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg mb-6 flex items-center">
<i class="fas fa-exclamation-circle mr-2"></i>
<span><?php echo $error; ?></span>
</div>
<?php endif; ?>
<!-- Events Table -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Dates</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Location</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Registration</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<?php if (empty($events)): ?>
<tr>
<td colspan="6" class="px-6 py-12 text-center text-gray-500">
<i class="fas fa-calendar-times text-4xl mb-4"></i>
<p>No events found. Create your first event!</p>
</td>
</tr>
<?php else: ?>
<?php foreach ($events as $event): ?>
<tr class="hover:bg-gray-50 transition">
<td class="px-6 py-4">
<div>
<div class="font-semibold text-gray-800"><?php echo htmlspecialchars($event['name']); ?></div>
<?php if (!empty($event['description'])): ?>
<div class="text-sm text-gray-500"><?php echo htmlspecialchars(substr($event['description'], 0, 100)) . (strlen($event['description']) > 100 ? '...' : ''); ?></div>
<?php endif; ?>
</div>
</td>
<td class="px-6 py-4 text-sm">
<?php if ($event['start_date']): ?>
<div class="text-gray-800">
<i class="fas fa-calendar mr-1"></i>
<?php echo date('M j, Y', strtotime($event['start_date'])); ?>
</div>
<?php if ($event['end_date'] && $event['end_date'] !== $event['start_date']): ?>
<div class="text-gray-500 text-xs">
to <?php echo date('M j, Y', strtotime($event['end_date'])); ?>
</div>
<?php endif; ?>
<?php else: ?>
<span class="text-gray-400">No date set</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-sm">
<?php if ($event['location_name']): ?>
<span class="text-gray-800"><?php echo htmlspecialchars($event['location_name']); ?></span>
<div class="text-xs text-gray-500 capitalize"><?php echo $event['location_type']; ?> Level</div>
<?php else: ?>
<span class="text-gray-400">General Event</span>
<?php endif; ?>
</td>
<td class="px-6 py-4">
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full
<?php
echo $event['registration_status'] === 'open' ? 'bg-green-100 text-green-800' :
($event['registration_status'] === 'closed' ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800');
?>">
<?php echo ucfirst($event['registration_status']); ?>
</span>
</td>
<td class="px-6 py-4">
<?php if ($event['is_active']): ?>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">
<i class="fas fa-check-circle mr-1"></i>Active
</span>
<?php else: ?>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-gray-100 text-gray-800">
<i class="fas fa-pause-circle mr-1"></i>Inactive
</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-sm">
<div class="flex space-x-2">
<button onclick="editEvent(<?php echo htmlspecialchars(json_encode($event)); ?>)"
class="text-blue-600 hover:text-blue-800 transition"
title="Edit">
<i class="fas fa-edit"></i>
</button>
<button onclick="deleteEvent(<?php echo $event['id']; ?>, '<?php echo htmlspecialchars($event['name']); ?>')"
class="text-red-600 hover:text-red-800 transition"
title="Delete">
<i class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
<!-- Event Modal -->
<div id="eventModal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50">
<div class="flex items-center justify-center min-h-screen p-4">
<div class="bg-white rounded-xl shadow-xl max-w-2xl w-full max-h-screen overflow-y-auto">
<div class="p-6">
<div class="flex justify-between items-center mb-6">
<h2 id="modalTitle" class="text-xl font-bold text-gray-800">Add Event</h2>
<button onclick="closeEventModal()" class="text-gray-400 hover:text-gray-600">
<i class="fas fa-times text-xl"></i>
</button>
</div>
<form id="eventForm" method="POST" action="">
<input type="hidden" id="event_id" name="event_id">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="md:col-span-2">
<label for="name" class="block text-sm font-medium text-gray-700 mb-2">Event Name *</label>
<input type="text" id="name" name="name" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div class="md:col-span-2">
<label for="description" class="block text-sm font-medium text-gray-700 mb-2">Description</label>
<textarea id="description" name="description" rows="3"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
</div>
<div>
<label for="start_date" class="block text-sm font-medium text-gray-700 mb-2">Start Date</label>
<input type="datetime-local" id="start_date" name="start_date"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label for="end_date" class="block text-sm font-medium text-gray-700 mb-2">End Date</label>
<input type="datetime-local" id="end_date" name="end_date"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label for="location_type" class="block text-sm font-medium text-gray-700 mb-2">Location Type</label>
<select id="location_type" name="location_type" onchange="loadLocations()" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Select Location Type</option>
<?php if ($accessLevel === 'superuser' || $accessLevel === 'area'): ?>
<option value="area">Area Level</option>
<?php endif; ?>
<?php if ($accessLevel === 'superuser' || $accessLevel === 'area' || $accessLevel === 'district'): ?>
<option value="district">District Level</option>
<?php endif; ?>
<option value="assembly">Assembly Level</option>
</select>
</div>
<div>
<label for="location_id" class="block text-sm font-medium text-gray-700 mb-2">Location</label>
<select id="location_id" name="location_id"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Select Location</option>
</select>
</div>
<div>
<label for="registration_status" class="block text-sm font-medium text-gray-700 mb-2">Registration Status</label>
<select id="registration_status" name="registration_status"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="pending">Pending</option>
<option value="open">Open</option>
<option value="closed">Closed</option>
</select>
</div>
<div>
<label for="registration_open_date" class="block text-sm font-medium text-gray-700 mb-2">Registration Opens</label>
<input type="datetime-local" id="registration_open_date" name="registration_open_date"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label for="registration_close_date" class="block text-sm font-medium text-gray-700 mb-2">Registration Closes</label>
<input type="datetime-local" id="registration_close_date" name="registration_close_date"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div class="md:col-span-2">
<label for="registration_message" class="block text-sm font-medium text-gray-700 mb-2">Registration Message</label>
<textarea id="registration_message" name="registration_message" rows="2"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
</div>
<div class="md:col-span-2">
<div class="flex items-center">
<input type="checkbox" id="is_active" name="is_active" value="1" checked
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<label for="is_active" class="ml-2 block text-sm text-gray-900">Active Event</label>
</div>
</div>
</div>
<div class="flex justify-end space-x-4 mt-6">
<button type="button" onclick="closeEventModal()"
class="px-6 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition">
Cancel
</button>
<button type="submit"
class="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">
<i class="fas fa-save mr-2"></i>Save Event
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
function openEventModal() {
document.getElementById('modalTitle').textContent = 'Add Event';
document.getElementById('eventForm').reset();
document.getElementById('event_id').value = '';
document.getElementById('eventModal').classList.remove('hidden');
}
function closeEventModal() {
document.getElementById('eventModal').classList.add('hidden');
}
function editEvent(event) {
document.getElementById('modalTitle').textContent = 'Edit Event';
document.getElementById('event_id').value = event.id;
document.getElementById('name').value = event.name;
document.getElementById('description').value = event.description || '';
if (event.start_date) {
document.getElementById('start_date').value = new Date(event.start_date).toISOString().slice(0, 16);
}
if (event.end_date) {
document.getElementById('end_date').value = new Date(event.end_date).toISOString().slice(0, 16);
}
document.getElementById('location_type').value = event.location_type || '';
document.getElementById('registration_status').value = event.registration_status;
if (event.registration_open_date) {
document.getElementById('registration_open_date').value = new Date(event.registration_open_date).toISOString().slice(0, 16);
}
if (event.registration_close_date) {
document.getElementById('registration_close_date').value = new Date(event.registration_close_date).toISOString().slice(0, 16);
}
document.getElementById('registration_message').value = event.registration_message || '';
document.getElementById('is_active').checked = event.is_active == 1;
// Load locations and set selected
loadLocations().then(() => {
if (event.location_id) {
document.getElementById('location_id').value = event.location_id;
}
});
document.getElementById('eventModal').classList.remove('hidden');
}
function deleteEvent(id, name) {
if (confirm(`Are you sure you want to delete the event "${name}"?`)) {
window.location.href = `?delete=${id}`;
}
}
async function loadLocations() {
const locationType = document.getElementById('location_type').value;
const locationSelect = document.getElementById('location_id');
locationSelect.innerHTML = '<option value="">Select Location</option>';
if (!locationType) return;
try {
const response = await fetch(`../../api/get-locations.php?type=${locationType}`);
const locations = await response.json();
locations.forEach(location => {
const option = document.createElement('option');
option.value = location.id;
option.textContent = location.name;
locationSelect.appendChild(option);
});
} catch (error) {
console.error('Error loading locations:', error);
}
}
// Close modal when clicking outside
document.getElementById('eventModal').addEventListener('click', function(e) {
if (e.target === this) {
closeEventModal();
}
});
</script>
<?php include '../../includes/footer.php'; ?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists