Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/programs/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/programs/realtime-attendance.php

<?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