Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/conference/admin/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/conference/admin/users.php

<?php
require_once '../includes/functions.php';

// Check if user is logged in and has admin privileges
if (!isLoggedIn()) {
    header('Location: ' . BASE_URL . 'login.php');
    exit();
}

$user = getCurrentUser();
if (!in_array($user['role'], ['superuser', 'area_admin', 'district_admin', 'assembly_admin'])) {
    header('Location: ' . BASE_URL . 'dashboard.php');
    exit();
}

$db = new CopMadinaDB();
$conn = $db->getConnection();

// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    
    if ($action === 'create') {
        $username = trim($_POST['username']);
        $email = trim($_POST['email']);
        $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
        $first_name = trim($_POST['first_name']);
        $last_name = trim($_POST['last_name']);
        $phone = trim($_POST['phone']);
        $role = $_POST['role'];
        $area_id = !empty($_POST['area_id']) ? $_POST['area_id'] : null;
        $district_id = !empty($_POST['district_id']) ? $_POST['district_id'] : null;
        $assembly_id = !empty($_POST['assembly_id']) ? $_POST['assembly_id'] : null;
        
        try {
            // Check if username or email already exists
            $check_stmt = executeQuery("SELECT id FROM users WHERE username = ? OR email = ?", [$username, $email]);
            if ($check_stmt && $check_stmt->fetch()) {
                addNotification('error', 'Username or email already exists.');
            } else {
                $stmt = executeQuery(
                    "INSERT INTO users (username, email, password, first_name, last_name, phone, role, area_id, district_id, assembly_id, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NOW())",
                    [$username, $email, $password, $first_name, $last_name, $phone, $role, $area_id, $district_id, $assembly_id]
                );
                
                if ($stmt) {
                    $new_user_id = $conn->lastInsertId();
                    if ($new_user_id > 0) {
                        logAudit('create', 'users', $new_user_id);
                        addNotification('success', 'User created successfully!');
                        
                        // Redirect to prevent form resubmission
                        header('Location: users.php?success=1');
                        exit();
                    } else {
                        addNotification('error', 'User creation failed - no ID returned.');
                    }
                } else {
                    addNotification('error', 'Failed to create user. Please check the form data.');
                }
            }
        } catch (Exception $e) {
            error_log("User creation error: " . $e->getMessage());
            addNotification('error', 'Database error: ' . $e->getMessage());
        }
    } elseif ($action === 'update') {
        $id = $_POST['id'];
        $username = trim($_POST['username']);
        $email = trim($_POST['email']);
        $first_name = trim($_POST['first_name']);
        $last_name = trim($_POST['last_name']);
        $phone = trim($_POST['phone']);
        $role = $_POST['role'];
        $status = $_POST['status'];
        
        $update_query = "UPDATE users SET username = ?, email = ?, first_name = ?, last_name = ?, phone = ?, role = ?, status = ? WHERE id = ?";
        $params = [$username, $email, $first_name, $last_name, $phone, $role, $status, $id];
        
        // Update password if provided
        if (!empty($_POST['password'])) {
            $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
            $update_query = "UPDATE users SET username = ?, email = ?, password = ?, first_name = ?, last_name = ?, phone = ?, role = ?, status = ? WHERE id = ?";
            $params = [$username, $email, $password, $first_name, $last_name, $phone, $role, $status, $id];
        }
        
        $stmt = executeQuery($update_query, $params);
        
        if ($stmt) {
            logAudit('update', 'users', $id);
            addNotification('success', 'User updated successfully!');
        } else {
            addNotification('error', 'Failed to update user.');
        }
    } elseif ($action === 'delete') {
        $id = $_POST['id'];
        
        $stmt = executeQuery("DELETE FROM users WHERE id = ?", [$id]);
        
        if ($stmt) {
            logAudit('delete', 'users', $id);
            addNotification('success', 'User deleted successfully!');
        } else {
            addNotification('error', 'Failed to delete user.');
        }
    }
    
    header('Location: users.php');
    exit();
}

// Get users based on role
$users_query = "SELECT u.*, a.name as area_name, d.name as district_name, ass.name as assembly_name FROM users u LEFT JOIN areas a ON u.area_id = a.id LEFT JOIN districts d ON u.district_id = d.id LEFT JOIN assemblies ass ON u.assembly_id = ass.id";
$params = [];

if ($user['role'] === 'area_admin') {
    $users_query .= " WHERE u.area_id = ? OR u.id = ?";
    $params = [$user['area_id'], $user['id']];
} elseif ($user['role'] === 'district_admin') {
    $users_query .= " WHERE u.district_id = ? OR u.id = ?";
    $params = [$user['district_id'], $user['id']];
} elseif ($user['role'] === 'assembly_admin') {
    $users_query .= " WHERE u.assembly_id = ? OR u.id = ?";
    $params = [$user['assembly_id'], $user['id']];
}

$users_query .= " ORDER BY u.created_at DESC";
$stmt = executeQuery($users_query, $params);
$users = $stmt ? $stmt->fetchAll() : [];

// Get areas, districts, assemblies for dropdowns
$areas = $districts = $assemblies = [];
if ($user['role'] === 'superuser') {
    $stmt = executeQuery("SELECT id, name FROM areas WHERE status = 'active' ORDER BY name");
    $areas = $stmt ? $stmt->fetchAll() : [];
    $stmt = executeQuery("SELECT id, name FROM districts WHERE status = 'active' ORDER BY name");
    $districts = $stmt ? $stmt->fetchAll() : [];
    $stmt = executeQuery("SELECT id, name FROM assemblies WHERE status = 'active' ORDER BY name");
    $assemblies = $stmt ? $stmt->fetchAll() : [];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Users Management - COP Madina Conference</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body class="bg-gradient-to-br from-slate-50 to-blue-50 min-h-screen">
    <div id="app" class="flex h-screen">
        <!-- Sidebar -->
        <?php include 'includes/admin_sidebar.php'; ?>
        
        <!-- Main Content -->
        <div class="flex-1 flex flex-col overflow-hidden ml-72">
            <!-- Header -->
            <header class="bg-white/80 backdrop-blur-sm shadow-lg border-b border-slate-200/50">
                <div class="flex items-center justify-between px-8 py-6">
                    <div>
                        <h1 class="text-3xl font-bold bg-gradient-to-r from-indigo-600 to-blue-600 bg-clip-text text-transparent flex items-center">
                            <div class="p-2 rounded-xl bg-gradient-to-br from-indigo-500 to-blue-600 mr-3">
                                <i class="fas fa-users text-white"></i>
                            </div>
                            Users Management
                        </h1>
                        <p class="text-slate-600 mt-1">Manage system users and permissions</p>
                    </div>
                    <button @click="showCreateModal = true" 
                            class="px-6 py-3 bg-gradient-to-r from-indigo-600 to-blue-600 hover:from-indigo-700 hover:to-blue-700 text-white font-medium rounded-xl transition-all duration-200 flex items-center space-x-2 shadow-lg">
                        <i class="fas fa-plus"></i>
                        <span>Add New User</span>
                    </button>
                </div>
            </header>

            <!-- Content -->
            <main class="flex-1 overflow-y-auto p-8">
                <!-- Users Table -->
                <div class="bg-white/70 backdrop-blur-sm rounded-2xl shadow-lg border border-slate-200/50">
                    <div class="overflow-x-auto">
                        <table class="w-full">
                            <thead class="bg-slate-50/50 border-b border-slate-200/50">
                                <tr>
                                    <th class="px-6 py-4 text-left text-sm font-semibold text-slate-700">User</th>
                                    <th class="px-6 py-4 text-left text-sm font-semibold text-slate-700">Role</th>
                                    <th class="px-6 py-4 text-left text-sm font-semibold text-slate-700">Assignment</th>
                                    <th class="px-6 py-4 text-left text-sm font-semibold text-slate-700">Status</th>
                                    <th class="px-6 py-4 text-left text-sm font-semibold text-slate-700">Created</th>
                                    <th class="px-6 py-4 text-center text-sm font-semibold text-slate-700">Actions</th>
                                </tr>
                            </thead>
                            <tbody class="divide-y divide-slate-200/50">
                                <?php foreach ($users as $u): ?>
                                <tr class="hover:bg-slate-50/50 transition-colors">
                                    <td class="px-6 py-4">
                                        <div class="flex items-center">
                                            <div class="w-10 h-10 bg-gradient-to-br from-indigo-500 to-blue-600 rounded-full flex items-center justify-center mr-3">
                                                <span class="text-white font-semibold text-sm">
                                                    <?php echo strtoupper(substr($u['first_name'], 0, 1) . substr($u['last_name'], 0, 1)); ?>
                                                </span>
                                            </div>
                                            <div>
                                                <div class="font-semibold text-slate-800"><?php echo htmlspecialchars($u['first_name'] . ' ' . $u['last_name']); ?></div>
                                                <div class="text-sm text-slate-600"><?php echo htmlspecialchars($u['email']); ?></div>
                                                <div class="text-xs text-slate-500">@<?php echo htmlspecialchars($u['username']); ?></div>
                                            </div>
                                        </div>
                                    </td>
                                    <td class="px-6 py-4">
                                        <span class="px-3 py-1 text-xs font-semibold rounded-full <?php 
                                            echo $u['role'] === 'superuser' ? 'bg-red-100 text-red-800' : 
                                                ($u['role'] === 'area_admin' ? 'bg-blue-100 text-blue-800' : 
                                                ($u['role'] === 'district_admin' ? 'bg-emerald-100 text-emerald-800' : 
                                                ($u['role'] === 'assembly_admin' ? 'bg-purple-100 text-purple-800' : 'bg-slate-100 text-slate-800'))); 
                                        ?>">
                                            <?php echo ucfirst(str_replace('_', ' ', $u['role'])); ?>
                                        </span>
                                    </td>
                                    <td class="px-6 py-4 text-sm text-slate-600">
                                        <?php 
                                        if ($u['area_name']) echo htmlspecialchars($u['area_name']);
                                        if ($u['district_name']) echo ($u['area_name'] ? ' > ' : '') . htmlspecialchars($u['district_name']);
                                        if ($u['assembly_name']) echo ($u['district_name'] ? ' > ' : '') . htmlspecialchars($u['assembly_name']);
                                        if (!$u['area_name'] && !$u['district_name'] && !$u['assembly_name']) echo 'System Wide';
                                        ?>
                                    </td>
                                    <td class="px-6 py-4">
                                        <span class="px-3 py-1 text-xs font-semibold rounded-full <?php echo $u['status'] === 'active' ? 'bg-emerald-100 text-emerald-800' : 'bg-red-100 text-red-800'; ?>">
                                            <?php echo ucfirst($u['status']); ?>
                                        </span>
                                    </td>
                                    <td class="px-6 py-4 text-sm text-slate-600">
                                        <?php echo date('M j, Y', strtotime($u['created_at'])); ?>
                                    </td>
                                    <td class="px-6 py-4 text-center">
                                        <div class="flex justify-center space-x-2">
                                            <button @click="editUser(<?php echo htmlspecialchars(json_encode($u)); ?>)"
                                                    class="px-3 py-1 bg-indigo-100 hover:bg-indigo-200 text-indigo-700 rounded-lg text-sm transition-colors">
                                                <i class="fas fa-edit"></i>
                                            </button>
                                            <?php if ($u['id'] != $user['id']): ?>
                                            <button @click="confirmDelete(<?php echo $u['id']; ?>, '<?php echo htmlspecialchars($u['first_name'] . ' ' . $u['last_name']); ?>')"
                                                    class="px-3 py-1 bg-red-100 hover:bg-red-200 text-red-700 rounded-lg text-sm transition-colors">
                                                <i class="fas fa-trash"></i>
                                            </button>
                                            <?php endif; ?>
                                        </div>
                                    </td>
                                </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                </div>

                <!-- Empty State -->
                <?php if (empty($users)): ?>
                <div class="text-center py-16">
                    <div class="mx-auto w-24 h-24 bg-slate-100 rounded-full flex items-center justify-center mb-6">
                        <i class="fas fa-users text-3xl text-slate-400"></i>
                    </div>
                    <h3 class="text-xl font-semibold text-slate-700 mb-2">No Users Found</h3>
                    <p class="text-slate-500 mb-6">Get started by creating your first user.</p>
                    <button @click="showCreateModal = true" 
                            class="px-6 py-3 bg-gradient-to-r from-indigo-600 to-blue-600 hover:from-indigo-700 hover:to-blue-700 text-white font-medium rounded-xl transition-all duration-200">
                        <i class="fas fa-plus mr-2"></i>
                        Create First User
                    </button>
                </div>
                <?php endif; ?>
            </main>
        </div>

        <!-- Create/Edit Modal -->
        <div v-if="showCreateModal || showEditModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
            <div class="bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto border border-slate-200/50">
                <div class="sticky top-0 bg-white/95 backdrop-blur-sm border-b border-slate-200/50 px-6 py-4 rounded-t-2xl">
                    <div class="flex items-center justify-between">
                        <h3 class="text-xl font-bold text-slate-800">
                            {{ showCreateModal ? 'Create New User' : 'Edit User' }}
                        </h3>
                        <button @click="closeModal()" class="p-2 rounded-lg hover:bg-slate-100 transition-colors">
                            <i class="fas fa-times text-slate-500"></i>
                        </button>
                    </div>
                </div>
                
                <form method="POST" class="p-6 space-y-6">
                    <input type="hidden" name="action" :value="showCreateModal ? 'create' : 'update'">
                    <input v-if="showEditModal" type="hidden" name="id" :value="editingUser.id">
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">First Name *</label>
                            <input type="text" name="first_name" :value="editingUser.first_name" required
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                        
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Last Name *</label>
                            <input type="text" name="last_name" :value="editingUser.last_name" required
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                    </div>
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Username *</label>
                            <input type="text" name="username" :value="editingUser.username" required
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                        
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Email *</label>
                            <input type="email" name="email" :value="editingUser.email" required
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                    </div>
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Phone</label>
                            <input type="tel" name="phone" :value="editingUser.phone"
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                        
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Password {{ showEditModal ? '(leave blank to keep current)' : '*' }}</label>
                            <input type="password" name="password" :required="showCreateModal"
                                   class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                        </div>
                    </div>
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Role *</label>
                            <select name="role" :value="editingUser.role" required
                                    class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                                <option value="">Select Role</option>
                                <?php if ($user['role'] === 'superuser'): ?>
                                <option value="superuser">Superuser</option>
                                <option value="area_admin">Area Admin</option>
                                <option value="district_admin">District Admin</option>
                                <option value="assembly_admin">Assembly Admin</option>
                                <?php elseif ($user['role'] === 'area_admin'): ?>
                                <option value="district_admin">District Admin</option>
                                <option value="assembly_admin">Assembly Admin</option>
                                <?php elseif ($user['role'] === 'district_admin'): ?>
                                <option value="assembly_admin">Assembly Admin</option>
                                <?php endif; ?>
                                <option value="member">Member</option>
                            </select>
                        </div>
                        
                        <div v-if="showEditModal">
                            <label class="block text-sm font-semibold text-slate-700 mb-2">Status</label>
                            <select name="status" :value="editingUser.status"
                                    class="w-full px-4 py-3 border border-slate-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200">
                                <option value="active">Active</option>
                                <option value="inactive">Inactive</option>
                            </select>
                        </div>
                    </div>
                    
                    <div class="flex justify-end space-x-3 pt-4 border-t border-slate-200">
                        <button type="button" @click="closeModal()" 
                                class="px-6 py-3 bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium rounded-xl transition-colors">
                            Cancel
                        </button>
                        <button type="submit" 
                                class="px-6 py-3 bg-gradient-to-r from-indigo-600 to-blue-600 hover:from-indigo-700 hover:to-blue-700 text-white font-medium rounded-xl transition-all duration-200 shadow-lg">
                            {{ showCreateModal ? 'Create User' : 'Update User' }}
                        </button>
                    </div>
                </form>
            </div>
        </div>

        <!-- Delete Confirmation Modal -->
        <div v-if="showDeleteModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
            <div class="bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl w-full max-w-md border border-slate-200/50">
                <div class="p-6 text-center">
                    <div class="mx-auto w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mb-4">
                        <i class="fas fa-exclamation-triangle text-red-600 text-2xl"></i>
                    </div>
                    <h3 class="text-xl font-bold text-slate-800 mb-2">Delete User</h3>
                    <p class="text-slate-600 mb-6">
                        Are you sure you want to delete <strong>"{{ deletingUserName }}"</strong>? This action cannot be undone.
                    </p>
                    <div class="flex justify-center space-x-3">
                        <form method="POST" class="flex space-x-3">
                            <input type="hidden" name="action" value="delete">
                            <input type="hidden" name="id" :value="deletingUserId">
                            <button type="button" @click="showDeleteModal = false" 
                                    class="px-6 py-3 bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium rounded-xl transition-colors">
                                Cancel
                            </button>
                            <button type="submit" 
                                    class="px-6 py-3 bg-red-600 hover:bg-red-700 text-white font-medium rounded-xl transition-colors">
                                Delete
                            </button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const { createApp } = Vue;
        
        createApp({
            data() {
                return {
                    showCreateModal: false,
                    showEditModal: false,
                    showDeleteModal: false,
                    editingUser: {},
                    deletingUserId: null,
                    deletingUserName: ''
                }
            },
            methods: {
                editUser(user) {
                    this.editingUser = { ...user };
                    this.showEditModal = true;
                },
                confirmDelete(id, name) {
                    this.deletingUserId = id;
                    this.deletingUserName = name;
                    this.showDeleteModal = true;
                },
                closeModal() {
                    this.showCreateModal = false;
                    this.showEditModal = false;
                    this.editingUser = {};
                }
            }
        }).mount('#app');
    </script>
</body>
</html>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists