Sindbad~EG File Manager
<?php
require_once '../../config/config.php';
checkLogin();
$pageTitle = "Manual Attendance Check-In - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$success = '';
$error = '';
$programId = $_GET['program_id'] ?? null;
$selectedDate = date('Y-m-d');
if (!$programId) {
$_SESSION['error'] = 'Please select a program';
header('Location: index.php');
exit();
}
// Get program details
$stmt = $db->prepare("SELECT * FROM programs WHERE id = :id");
$stmt->execute(['id' => $programId]);
$program = $stmt->fetch();
if (!$program) {
$_SESSION['error'] = 'Program not found';
header('Location: index.php');
exit();
}
// Handle manual check-in
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['manual_checkin'])) {
try {
$memberId = $_POST['member_id'];
$stmt = $db->prepare("
INSERT INTO program_attendance (program_id, member_id, attendance_date, status, marked_by, check_in_time)
VALUES (:program_id, :member_id, :attendance_date, 'present', :marked_by, NOW())
ON DUPLICATE KEY UPDATE status = 'present', check_in_time = NOW(), marked_by = :marked_by
");
$stmt->execute([
'program_id' => $programId,
'member_id' => $memberId,
'attendance_date' => $selectedDate,
'marked_by' => $_SESSION['user_id']
]);
$success = "Member checked in successfully!";
} catch (Exception $e) {
$error = "Error: " . $e->getMessage();
}
}
// Handle manual check-out
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['manual_checkout'])) {
try {
$memberId = $_POST['member_id'];
// Check if member is checked in
$checkStmt = $db->prepare("
SELECT id FROM program_attendance
WHERE program_id = :program_id AND member_id = :member_id AND attendance_date = :date
");
$checkStmt->execute([
'program_id' => $programId,
'member_id' => $memberId,
'date' => $selectedDate
]);
if (!$checkStmt->fetch()) {
throw new Exception("Member not checked in yet");
}
$stmt = $db->prepare("
UPDATE program_attendance
SET check_out_time = NOW(), marked_by = :marked_by
WHERE program_id = :program_id AND member_id = :member_id AND attendance_date = :date
");
$stmt->execute([
'program_id' => $programId,
'member_id' => $memberId,
'date' => $selectedDate,
'marked_by' => $_SESSION['user_id']
]);
$success = "Member checked out successfully!";
} catch (Exception $e) {
$error = "Error: " . $e->getMessage();
}
}
// Get real-time attendance stats
$statsStmt = $db->prepare("
SELECT
COUNT(DISTINCT pa.member_id) as checked_in,
(SELECT COUNT(*) FROM members WHERE is_active = 1) as total_members
FROM program_attendance pa
WHERE pa.program_id = :program_id AND pa.attendance_date = :date
");
$statsStmt->execute(['program_id' => $programId, 'date' => $selectedDate]);
$stats = $statsStmt->fetch();
// Get recently checked-in members
$recentStmt = $db->prepare("
SELECT m.id, m.first_name, m.last_name, m.membershipcard_id, pa.check_in_time, pa.check_out_time
FROM program_attendance pa
JOIN members m ON pa.member_id = m.id
WHERE pa.program_id = :program_id AND pa.attendance_date = :date
ORDER BY pa.check_in_time DESC
LIMIT 50
");
$recentStmt->execute(['program_id' => $programId, 'date' => $selectedDate]);
$recentCheckIns = $recentStmt->fetchAll();
// Get members for attendance with filters
$query = "
SELECT m.id, m.first_name, m.last_name, m.membershipcard_id,
pa.check_in_time, pa.check_out_time
FROM members m
LEFT JOIN program_attendance pa ON m.id = pa.member_id
AND pa.program_id = :program_id
AND pa.attendance_date = :date
WHERE m.is_active = 1
ORDER BY m.first_name, m.last_name
";
$membersStmt = $db->prepare($query);
$membersStmt->execute(['program_id' => $programId, 'date' => $selectedDate]);
$allMembers = $membersStmt->fetchAll();
include '../../includes/header.php';
?>
<?php include '../../includes/sidebar.php'; ?>
<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="mb-6 flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold text-gray-800">
<i class="fas fa-clipboard-check mr-2 text-blue-500"></i>Manual Attendance Check-In
</h1>
<p class="text-gray-600 mt-2"><?php echo htmlspecialchars($program['program_name']); ?> - <?php echo date('F j, Y'); ?></p>
</div>
<a href="index.php" class="bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition">
<i class="fas fa-arrow-left mr-2"></i>Back to Programs
</a>
</div>
<!-- Success/Error Messages -->
<?php if ($success): ?>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-check-circle mr-2"></i><?php echo $success; ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-exclamation-circle mr-2"></i><?php echo $error; ?>
</div>
<?php endif; ?>
<!-- Real-Time Stats -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<div class="bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex items-center justify-between">
<div>
<p class="text-sm opacity-90">Checked In</p>
<p class="text-4xl font-bold" id="checkedInCount"><?php echo $stats['checked_in']; ?></p>
</div>
<i class="fas fa-user-check text-5xl opacity-20"></i>
</div>
</div>
<div class="bg-gradient-to-r from-green-500 to-green-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex items-center justify-between">
<div>
<p class="text-sm opacity-90">Total Members</p>
<p class="text-4xl font-bold"><?php echo $stats['total_members']; ?></p>
</div>
<i class="fas fa-users text-5xl opacity-20"></i>
</div>
</div>
<div class="bg-gradient-to-r from-purple-500 to-purple-600 rounded-xl shadow-lg p-6 text-white">
<div class="flex items-center justify-between">
<div>
<p class="text-sm opacity-90">Attendance Rate</p>
<p class="text-4xl font-bold" id="attendanceRate">
<?php echo $stats['total_members'] > 0 ? round(($stats['checked_in'] / $stats['total_members']) * 100) : 0; ?>%
</p>
</div>
<i class="fas fa-chart-pie text-5xl opacity-20"></i>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Manual Check-in Search -->
<div class="lg:col-span-1">
<div class="bg-white rounded-xl shadow-lg p-6">
<h3 class="text-xl font-bold text-gray-800 mb-4">
<i class="fas fa-search mr-2 text-blue-500"></i>Quick Check-In
</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Search Member</label>
<input type="text" id="memberSearch"
placeholder="Type member name or card ID..."
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
</div>
<div id="searchResults" class="max-h-96 overflow-y-auto"></div>
</div>
</div>
<!-- Recent Check-ins -->
<div class="lg:col-span-1">
<div class="bg-white rounded-xl shadow-lg p-6">
<h3 class="text-xl font-bold text-gray-800 mb-4">
<i class="fas fa-list mr-2 text-green-500"></i>Recent Check-Ins
<span class="text-sm font-normal text-gray-500">(Updates automatically)</span>
</h3>
<div id="recentCheckIns" class="space-y-3 max-h-[600px] overflow-y-auto">
<?php if (empty($recentCheckIns)): ?>
<p class="text-gray-500 text-center py-8">No check-ins yet</p>
<?php else: ?>
<?php foreach ($recentCheckIns as $checkin): ?>
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg border border-gray-200 hover:shadow-md transition">
<div class="flex items-center">
<div class="h-12 w-12 rounded-full bg-gradient-to-r from-blue-500 to-purple-500 flex items-center justify-center text-white font-bold mr-4">
<?php echo strtoupper(substr($checkin['first_name'], 0, 1) . substr($checkin['last_name'], 0, 1)); ?>
</div>
<div>
<p class="font-semibold text-gray-900">
<?php echo htmlspecialchars($checkin['first_name'] . ' ' . $checkin['last_name']); ?>
</p>
<p class="text-sm text-gray-500">ID: <?php echo htmlspecialchars($checkin['membershipcard_id']); ?></p>
</div>
</div>
<div class="text-right">
<?php if ($checkin['check_out_time']): ?>
<p class="text-sm text-blue-600 font-semibold">
<i class="fas fa-sign-out-alt mr-1"></i>Checked Out
</p>
<p class="text-xs text-gray-500">
In: <?php echo date('g:i A', strtotime($checkin['check_in_time'])); ?>
</p>
<p class="text-xs text-gray-500">
Out: <?php echo date('g:i A', strtotime($checkin['check_out_time'])); ?>
</p>
<?php else: ?>
<p class="text-sm text-green-600 font-semibold">
<i class="fas fa-check-circle mr-1"></i>Checked In
</p>
<p class="text-xs text-gray-500">
<?php echo date('g:i A', strtotime($checkin['check_in_time'])); ?>
</p>
<button onclick="manualCheckOut(<?php echo $checkin['id']; ?>, '<?php echo htmlspecialchars($checkin['first_name'] . ' ' . $checkin['last_name']); ?>')"
class="mt-1 text-xs text-orange-600 hover:text-orange-800">
<i class="fas fa-sign-out-alt mr-1"></i>Check Out
</button>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<script>
// Member search for quick check-in
const memberSearch = document.getElementById('memberSearch');
const searchResults = document.getElementById('searchResults');
const allMembers = <?php echo json_encode($allMembers); ?>;
memberSearch.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
if (searchTerm.length < 2) {
searchResults.innerHTML = '';
return;
}
const filtered = allMembers.filter(m =>
(m.first_name + ' ' + m.last_name).toLowerCase().includes(searchTerm) ||
(m.membershipcard_id || '').toLowerCase().includes(searchTerm)
).slice(0, 10);
if (filtered.length === 0) {
searchResults.innerHTML = '<p class="text-gray-500 text-sm p-2">No members found</p>';
return;
}
searchResults.innerHTML = filtered.map(m => {
let statusHtml = '';
if (m.check_out_time) {
statusHtml = '<span class="text-xs text-blue-600"><i class="fas fa-sign-out-alt"></i> Checked Out</span>';
} else if (m.check_in_time) {
statusHtml = `
<div class="flex gap-1">
<span class="text-xs text-green-600"><i class="fas fa-check"></i> In</span>
<button onclick="event.stopPropagation(); manualCheckOut(${m.id}, '${m.first_name} ${m.last_name}')"
class="text-xs text-orange-600 hover:text-orange-800">
<i class="fas fa-sign-out-alt"></i> Out
</button>
</div>
`;
} else {
statusHtml = '<button class="text-blue-600 text-xs">Check In</button>';
}
return `
<div class="p-2 hover:bg-gray-100 rounded cursor-pointer flex justify-between items-center"
${m.check_in_time && !m.check_out_time ? '' : `onclick="manualCheckIn(${m.id}, '${m.first_name} ${m.last_name}')"`}>
<span class="text-sm">
<strong>${m.first_name} ${m.last_name}</strong>
<br><span class="text-xs text-gray-500">ID: ${m.membershipcard_id || 'N/A'}</span>
</span>
${statusHtml}
</div>
`;
}).join('');
});
function manualCheckIn(memberId, memberName) {
if (confirm(`Check in ${memberName}?`)) {
const formData = new FormData();
formData.append('manual_checkin', '1');
formData.append('member_id', memberId);
fetch('', {
method: 'POST',
body: formData
}).then(() => {
location.reload();
});
}
}
function manualCheckOut(memberId, memberName) {
if (confirm(`Check out ${memberName}?`)) {
const formData = new FormData();
formData.append('manual_checkout', '1');
formData.append('member_id', memberId);
fetch('', {
method: 'POST',
body: formData
}).then(() => {
location.reload();
});
}
}
</script>
<?php include '../../includes/footer.php'; ?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists