Sindbad~EG File Manager
<?php
require_once 'config/config.php';
$pageTitle = "Guest Check-In - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$stmt = $db->query("SELECT * FROM general_settings ORDER BY id DESC LIMIT 1");
$settings = $stmt->fetch();
$settings = array_merge([
'site_title' => 'Church Membership System',
'theme_primary_color' => '#1E40AF',
'theme_secondary_color' => '#F97316',
], $settings ?: []);
$error = '';
$success = '';
$visitorCode = '';
$guestData = null;
// Get areas for dropdown
$areas = $db->query("SELECT id, area_name FROM areas WHERE is_active = 1 ORDER BY area_name")->fetchAll();
// Get districts for dropdown
$districts = $db->query("SELECT id, district_name, area_id FROM districts WHERE is_active = 1 ORDER BY district_name")->fetchAll();
// Get assemblies for dropdown
$assemblies = $db->query("SELECT id, assembly_name, district_id FROM assemblies WHERE is_active = 1 ORDER BY assembly_name")->fetchAll();
// Get active programs
$programs = $db->query("SELECT id, program_name FROM programs WHERE is_active = 1 ORDER BY program_name")->fetchAll();
// Generate visitor code function
function generateVisitorCode() {
return 'VIS' . date('Y') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
}
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['guest_register'])) {
try {
$fullName = trim($_POST['full_name']);
$phone = trim($_POST['phone'] ?? '');
$email = trim($_POST['email'] ?? '');
$visitorType = $_POST['visitor_type'] ?? 'visitor';
$purposeOfVisit = trim($_POST['purpose_of_visit'] ?? '');
$areaId = !empty($_POST['area_id']) ? intval($_POST['area_id']) : null;
$districtId = !empty($_POST['district_id']) ? intval($_POST['district_id']) : null;
$assemblyId = !empty($_POST['assembly_id']) ? intval($_POST['assembly_id']) : null;
$programId = !empty($_POST['program_id']) ? intval($_POST['program_id']) : null;
// Validation
if (empty($fullName)) {
throw new Exception("Please enter your full name.");
}
if (empty($phone) && empty($email)) {
throw new Exception("Please provide at least a phone number or email address.");
}
if (empty($areaId)) {
throw new Exception("Please select an area.");
}
if (empty($districtId)) {
throw new Exception("Please select a district.");
}
if (empty($assemblyId)) {
throw new Exception("Please select an assembly.");
}
// Generate unique visitor code
$visitorCode = generateVisitorCode();
// Check if code already exists (unlikely but safe)
$checkStmt = $db->prepare("SELECT id FROM guest_visitors WHERE visitor_code = :code");
$checkStmt->execute(['code' => $visitorCode]);
while ($checkStmt->fetch()) {
$visitorCode = generateVisitorCode();
$checkStmt->execute(['code' => $visitorCode]);
}
// Insert guest record
$insertStmt = $db->prepare("
INSERT INTO guest_visitors (visitor_code, full_name, phone, email, visitor_type, purpose_of_visit, area_id, district_id, assembly_id, program_id, check_in_time)
VALUES (:visitor_code, :full_name, :phone, :email, :visitor_type, :purpose_of_visit, :area_id, :district_id, :assembly_id, :program_id, NOW())
");
$insertStmt->execute([
'visitor_code' => $visitorCode,
'full_name' => $fullName,
'phone' => $phone ?: null,
'email' => $email ?: null,
'visitor_type' => $visitorType,
'purpose_of_visit' => $purposeOfVisit ?: null,
'area_id' => $areaId,
'district_id' => $districtId,
'assembly_id' => $assemblyId,
'program_id' => $programId
]);
$guestId = $db->lastInsertId();
// Get guest data for display
$guestStmt = $db->prepare("
SELECT gv.*, ar.area_name, d.district_name, a.assembly_name, p.program_name
FROM guest_visitors gv
LEFT JOIN areas ar ON gv.area_id = ar.id
LEFT JOIN districts d ON gv.district_id = d.id
LEFT JOIN assemblies a ON gv.assembly_id = a.id
LEFT JOIN programs p ON gv.program_id = p.id
WHERE gv.id = :id
");
$guestStmt->execute(['id' => $guestId]);
$guestData = $guestStmt->fetch();
// Send email notification if email provided
$emailSent = false;
if (!empty($email)) {
try {
// Check if NotificationManager exists
if (class_exists('NotificationManager')) {
$notificationManager = new NotificationManager($db);
$emailSubject = "Welcome to " . $settings['site_title'] . " - Your Visitor Code";
$emailBody = "
<h2>Welcome, {$fullName}!</h2>
<p>Thank you for visiting us. Your visitor registration has been completed successfully.</p>
<div style='background: #f3f4f6; padding: 20px; border-radius: 10px; margin: 20px 0; text-align: center;'>
<p style='margin: 0; color: #666;'>Your Visitor Code:</p>
<h1 style='margin: 10px 0; color: #1E40AF; font-size: 32px; letter-spacing: 3px;'>{$visitorCode}</h1>
</div>
<p><strong>Details Submitted:</strong></p>
<ul>
<li>Name: {$fullName}</li>
<li>Type: " . ucfirst($visitorType) . "</li>
<li>Purpose: " . ($purposeOfVisit ?: 'Not specified') . "</li>
<li>Check-in Time: " . date('F j, Y g:i A') . "</li>
</ul>
<p>You can use this code to check your attendance details at any time by visiting:</p>
<p><a href='" . BASE_URL . "/guest-lookup.php'>Guest Lookup Page</a></p>
<p>God bless you!</p>
";
$notificationManager->sendEmail($email, $emailSubject, $emailBody);
$emailSent = true;
// Update email_sent flag
$db->prepare("UPDATE guest_visitors SET email_sent = 1 WHERE id = :id")->execute(['id' => $guestId]);
}
} catch (Exception $e) {
error_log("Failed to send guest email: " . $e->getMessage());
}
}
// Send SMS notification if phone provided
$smsSent = false;
if (!empty($phone)) {
try {
if (class_exists('NotificationManager')) {
$notificationManager = new NotificationManager($db);
$smsMessage = "Welcome to " . $settings['site_title'] . "! Your visitor code is: {$visitorCode}. Use this code to check your attendance details. God bless!";
$notificationManager->sendSMS($phone, $smsMessage);
$smsSent = true;
// Update sms_sent flag
$db->prepare("UPDATE guest_visitors SET sms_sent = 1 WHERE id = :id")->execute(['id' => $guestId]);
}
} catch (Exception $e) {
error_log("Failed to send guest SMS: " . $e->getMessage());
}
}
$success = "Registration successful! Your visitor code has been generated.";
} catch (Exception $e) {
$error = $e->getMessage();
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $pageTitle; ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
.hero-gradient { background: linear-gradient(135deg, #F97316 0%, #FBBF24 50%, #F59E0B 100%); }
.text-gradient { background: linear-gradient(135deg, #F97316 0%, #FBBF24 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.btn-gradient { background: linear-gradient(135deg, #F97316 0%, #FBBF24 100%); }
.card-hover:hover { transform: translateY(-3px); box-shadow: 0 15px 30px rgba(0,0,0,0.12); }
.card-hover { transition: all 0.3s ease; }
@keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
.animate-fadeIn { animation: fadeInUp 0.5s ease-out; }
@keyframes pulse-code { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.02); } }
.pulse-code { animation: pulse-code 2s ease-in-out infinite; }
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Header -->
<header class="bg-white shadow-lg sticky top-0 z-50">
<div class="container mx-auto px-4">
<div class="flex items-center justify-between h-16">
<div class="flex items-center space-x-3">
<div class="w-12 h-12 rounded-xl flex items-center justify-center hero-gradient">
<i class="fas fa-church text-white text-xl"></i>
</div>
<div>
<h1 class="text-xl font-bold text-gradient"><?php echo htmlspecialchars($settings['site_title']); ?></h1>
<p class="text-xs text-gray-500">Guest Registration</p>
</div>
</div>
<nav class="flex items-center space-x-4">
<a href="attendance.php" class="text-gray-700 hover:text-orange-600 font-medium transition">
<i class="fas fa-arrow-left mr-1"></i><span class="hidden sm:inline">Back</span>
</a>
<a href="index.php" class="text-gray-700 hover:text-blue-700 font-medium transition">
<i class="fas fa-home mr-1"></i><span class="hidden sm:inline">Home</span>
</a>
</nav>
</div>
</div>
</header>
<!-- Hero Section -->
<section class="hero-gradient text-white py-8">
<div class="container mx-auto px-4 text-center">
<i class="fas fa-user-plus text-5xl mb-3 opacity-90"></i>
<h1 class="text-3xl font-bold mb-2">Guest / Visitor Check-In</h1>
<p class="text-white/90">Welcome! Please fill in your details to register</p>
</div>
</section>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
<div class="max-w-2xl mx-auto">
<?php if ($error): ?>
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded mb-6 animate-fadeIn">
<p class="font-bold"><i class="fas fa-exclamation-circle mr-2"></i>Error</p>
<p><?php echo htmlspecialchars($error); ?></p>
</div>
<?php endif; ?>
<?php if ($guestData): ?>
<!-- Success - Show Visitor Code -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden animate-fadeIn">
<!-- Success Header -->
<div class="bg-gradient-to-r from-green-500 to-emerald-600 text-white p-6 text-center">
<div class="w-20 h-20 mx-auto mb-4 rounded-full bg-white/20 flex items-center justify-center">
<i class="fas fa-check text-4xl"></i>
</div>
<h2 class="text-2xl font-bold mb-2">Welcome, <?php echo htmlspecialchars($guestData['full_name']); ?>!</h2>
<p class="text-white/90">Your registration is complete</p>
</div>
<div class="p-6">
<!-- Visitor Code Display -->
<div class="bg-gradient-to-r from-orange-50 to-yellow-50 border-2 border-orange-200 rounded-xl p-6 text-center mb-6 pulse-code">
<p class="text-gray-600 mb-2">Your Visitor Code:</p>
<h1 class="text-4xl font-bold text-orange-600 tracking-widest mb-2"><?php echo htmlspecialchars($guestData['visitor_code']); ?></h1>
<p class="text-sm text-gray-500">Save this code to check your attendance details later</p>
</div>
<!-- Details Summary -->
<div class="bg-gray-50 rounded-lg p-4 mb-6">
<h4 class="font-bold text-gray-800 mb-3"><i class="fas fa-info-circle mr-2 text-blue-500"></i>Your Details</h4>
<div class="grid grid-cols-2 gap-3 text-sm">
<div>
<p class="text-gray-500">Name</p>
<p class="font-medium"><?php echo htmlspecialchars($guestData['full_name']); ?></p>
</div>
<div>
<p class="text-gray-500">Type</p>
<p class="font-medium"><?php echo ucfirst($guestData['visitor_type']); ?></p>
</div>
<?php if ($guestData['phone']): ?>
<div>
<p class="text-gray-500">Phone</p>
<p class="font-medium"><?php echo htmlspecialchars($guestData['phone']); ?></p>
</div>
<?php endif; ?>
<?php if ($guestData['email']): ?>
<div>
<p class="text-gray-500">Email</p>
<p class="font-medium"><?php echo htmlspecialchars($guestData['email']); ?></p>
</div>
<?php endif; ?>
<div>
<p class="text-gray-500">Check-in Time</p>
<p class="font-medium"><?php echo date('g:i A', strtotime($guestData['check_in_time'])); ?></p>
</div>
<?php if ($guestData['assembly_name']): ?>
<div>
<p class="text-gray-500">Assembly</p>
<p class="font-medium"><?php echo htmlspecialchars($guestData['assembly_name']); ?></p>
</div>
<?php endif; ?>
</div>
</div>
<!-- Notification Status -->
<div class="flex flex-wrap gap-3 mb-6">
<?php if ($guestData['email_sent']): ?>
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm">
<i class="fas fa-envelope mr-1"></i>Email sent
</span>
<?php endif; ?>
<?php if ($guestData['sms_sent']): ?>
<span class="bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm">
<i class="fas fa-sms mr-1"></i>SMS sent
</span>
<?php endif; ?>
</div>
<!-- Actions -->
<div class="flex flex-col sm:flex-row gap-3">
<a href="guest-lookup.php?code=<?php echo urlencode($guestData['visitor_code']); ?>"
class="flex-1 text-center py-3 btn-gradient text-white rounded-lg font-semibold">
<i class="fas fa-search mr-2"></i>View My Details
</a>
<a href="attendance.php" class="flex-1 text-center py-3 bg-gray-200 text-gray-700 rounded-lg font-semibold hover:bg-gray-300">
<i class="fas fa-arrow-left mr-2"></i>Back to Attendance
</a>
</div>
</div>
</div>
<?php else: ?>
<!-- Registration Form -->
<div class="bg-white rounded-xl shadow-lg p-8 animate-fadeIn">
<form method="POST" class="space-y-6">
<!-- Personal Information -->
<div>
<h3 class="text-lg font-bold text-gray-800 mb-4">
<i class="fas fa-user mr-2 text-orange-500"></i>Personal Information
</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Full Name <span class="text-red-500">*</span>
</label>
<input type="text" name="full_name" required autofocus
placeholder="Enter your full name"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Phone Number
</label>
<input type="tel" name="phone"
placeholder="e.g., 0241234567"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Email Address
</label>
<input type="email" name="email"
placeholder="email@example.com"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
</div>
</div>
<p class="text-xs text-gray-500"><i class="fas fa-info-circle mr-1"></i>Please provide at least a phone number or email to receive your visitor code.</p>
</div>
</div>
<!-- Visit Information -->
<div class="border-t pt-6">
<h3 class="text-lg font-bold text-gray-800 mb-4">
<i class="fas fa-clipboard-list mr-2 text-orange-500"></i>Visit Information
</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
I am a <span class="text-red-500">*</span>
</label>
<div class="grid grid-cols-3 gap-3">
<label class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-lg cursor-pointer hover:border-orange-400 transition has-[:checked]:border-orange-500 has-[:checked]:bg-orange-50">
<input type="radio" name="visitor_type" value="visitor" class="sr-only" checked>
<span class="text-center">
<i class="fas fa-walking text-2xl text-gray-600 mb-1 block"></i>
<span class="text-sm font-medium">Visitor</span>
</span>
</label>
<label class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-lg cursor-pointer hover:border-orange-400 transition has-[:checked]:border-orange-500 has-[:checked]:bg-orange-50">
<input type="radio" name="visitor_type" value="guest" class="sr-only">
<span class="text-center">
<i class="fas fa-user-friends text-2xl text-gray-600 mb-1 block"></i>
<span class="text-sm font-medium">Guest</span>
</span>
</label>
<label class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-lg cursor-pointer hover:border-orange-400 transition has-[:checked]:border-orange-500 has-[:checked]:bg-orange-50">
<input type="radio" name="visitor_type" value="first_timer" class="sr-only">
<span class="text-center">
<i class="fas fa-star text-2xl text-gray-600 mb-1 block"></i>
<span class="text-sm font-medium">First Timer</span>
</span>
</label>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Purpose of Visit
</label>
<textarea name="purpose_of_visit" rows="3"
placeholder="What brings you here today? (Optional)"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent"></textarea>
</div>
<!-- Location Fields -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Area <span class="text-red-500">*</span>
</label>
<select name="area_id" id="area_id" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
<option value="">Select Area</option>
<?php foreach ($areas as $area): ?>
<option value="<?php echo $area['id']; ?>"><?php echo htmlspecialchars($area['area_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
District <span class="text-red-500">*</span>
</label>
<select name="district_id" id="district_id" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
<option value="">Select District</option>
<?php foreach ($districts as $district): ?>
<option value="<?php echo $district['id']; ?>" data-area="<?php echo $district['area_id']; ?>"><?php echo htmlspecialchars($district['district_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Assembly <span class="text-red-500">*</span>
</label>
<select name="assembly_id" id="assembly_id" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
<option value="">Select Assembly</option>
<?php foreach ($assemblies as $assembly): ?>
<option value="<?php echo $assembly['id']; ?>" data-district="<?php echo $assembly['district_id']; ?>"><?php echo htmlspecialchars($assembly['assembly_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Program (Optional)
</label>
<select name="program_id" id="program_id" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent">
<option value="">Select Assembly first to see programs</option>
</select>
<p class="text-xs text-gray-500 mt-1"><i class="fas fa-info-circle mr-1"></i>Programs will load after selecting an assembly</p>
</div>
</div>
</div>
<!-- Submit -->
<div class="border-t pt-6">
<button type="submit" name="guest_register"
class="w-full py-4 btn-gradient text-white rounded-lg font-bold text-lg transition hover:shadow-lg">
<i class="fas fa-check-circle mr-2"></i>Complete Registration
</button>
<p class="text-center text-sm text-gray-500 mt-4">
By registering, you agree to share your information with the church for attendance purposes.
</p>
</div>
</form>
</div>
<?php endif; ?>
<!-- Already registered? -->
<?php if (!$guestData): ?>
<div class="mt-6 text-center">
<p class="text-gray-600">Already registered?</p>
<a href="guest-lookup.php" class="text-orange-600 hover:text-orange-800 font-medium">
<i class="fas fa-search mr-1"></i>Look up your details with your visitor code
</a>
</div>
<?php endif; ?>
</div>
</main>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-6 mt-auto">
<div class="container mx-auto px-4 text-center">
<p class="text-gray-400 text-sm">
© <?php echo date('Y'); ?> <?php echo htmlspecialchars($settings['site_title']); ?>
</p>
</div>
</footer>
<script>
// Radio button visual feedback
document.querySelectorAll('input[type="radio"]').forEach(radio => {
radio.addEventListener('change', function() {
document.querySelectorAll('input[name="' + this.name + '"]').forEach(r => {
r.closest('label').classList.remove('border-orange-500', 'bg-orange-50');
r.closest('label').classList.add('border-gray-200');
});
if (this.checked) {
this.closest('label').classList.remove('border-gray-200');
this.closest('label').classList.add('border-orange-500', 'bg-orange-50');
}
});
});
// Initialize checked state
document.querySelectorAll('input[type="radio"]:checked').forEach(radio => {
radio.closest('label').classList.remove('border-gray-200');
radio.closest('label').classList.add('border-orange-500', 'bg-orange-50');
});
// Cascading dropdowns for Area -> District -> Assembly
const areaSelect = document.getElementById('area_id');
const districtSelect = document.getElementById('district_id');
const assemblySelect = document.getElementById('assembly_id');
if (areaSelect && districtSelect) {
areaSelect.addEventListener('change', function() {
const selectedArea = this.value;
const districtOptions = districtSelect.querySelectorAll('option');
districtOptions.forEach(option => {
if (option.value === '') {
option.style.display = '';
return;
}
const optionArea = option.getAttribute('data-area');
option.style.display = (!selectedArea || optionArea === selectedArea) ? '' : 'none';
});
// Reset district if hidden
if (districtSelect.value) {
const currentOption = districtSelect.querySelector(`option[value="${districtSelect.value}"]`);
if (currentOption && currentOption.style.display === 'none') {
districtSelect.value = '';
districtSelect.dispatchEvent(new Event('change'));
}
}
});
}
if (districtSelect && assemblySelect) {
districtSelect.addEventListener('change', function() {
const selectedDistrict = this.value;
const assemblyOptions = assemblySelect.querySelectorAll('option');
assemblyOptions.forEach(option => {
if (option.value === '') {
option.style.display = '';
return;
}
const optionDistrict = option.getAttribute('data-district');
option.style.display = (!selectedDistrict || optionDistrict === selectedDistrict) ? '' : 'none';
});
// Reset assembly if hidden
if (assemblySelect.value) {
const currentOption = assemblySelect.querySelector(`option[value="${assemblySelect.value}"]`);
if (currentOption && currentOption.style.display === 'none') {
assemblySelect.value = '';
// Also reset programs
loadProgramsForAssembly('');
}
}
});
}
// Load programs based on selected assembly
const programSelect = document.getElementById('program_id');
if (assemblySelect && programSelect) {
assemblySelect.addEventListener('change', function() {
const assemblyId = this.value;
loadProgramsForAssembly(assemblyId);
});
}
function loadProgramsForAssembly(assemblyId) {
if (!assemblyId) {
programSelect.innerHTML = '<option value="">Select Assembly first to see programs</option>';
return;
}
programSelect.innerHTML = '<option value="">Loading programs...</option>';
fetch('api/get-programs.php?assembly_id=' + assemblyId)
.then(response => response.json())
.then(data => {
programSelect.innerHTML = '<option value="">Select Program (Optional)</option>';
if (data.success && data.programs && data.programs.length > 0) {
data.programs.forEach(program => {
const option = document.createElement('option');
option.value = program.id;
option.textContent = program.program_name;
programSelect.appendChild(option);
});
} else {
programSelect.innerHTML = '<option value="">No programs available for this assembly</option>';
}
})
.catch(error => {
console.error('Error loading programs:', error);
programSelect.innerHTML = '<option value="">Error loading programs</option>';
});
}
</script>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists