Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/portal/modules/membership/member_transfer.php

<?php
require_once '../../config/config.php';
checkLogin();

$pageTitle = 'Member Transfer - ' . APP_NAME;
$db = Database::getInstance()->getConnection();

$success = '';
$error = '';

// Access
$accessLevel = $_SESSION['access_level'] ?? 'assembly';
$areaId = $_SESSION['area_id'] ?? null;
$districtId = $_SESSION['district_id'] ?? null;
$assemblyId = $_SESSION['assembly_id'] ?? null;
$userId = $_SESSION['user_id'] ?? null;

// Handle transfer submit
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['transfer_members'])) {
    $memberIds = isset($_POST['member_ids']) && is_array($_POST['member_ids'])
        ? array_filter($_POST['member_ids'], 'is_numeric')
        : [];

    $toAreaId = (int)($_POST['to_area_id'] ?? 0);
    $toDistrictId = (int)($_POST['to_district_id'] ?? 0);
    $toAssemblyId = (int)($_POST['to_assembly_id'] ?? 0);

    if (empty($memberIds)) {
        $error = 'Please select at least one member to transfer.';
    } elseif ($toAreaId <= 0 || $toDistrictId <= 0 || $toAssemblyId <= 0) {
        $error = 'Please select Area, District and Assembly to transfer to.';
    } else {
        try {
            $db->beginTransaction();

            $now = date('Y-m-d H:i:s');

            foreach ($memberIds as $mid) {
                // Load current location
                $stmt = $db->prepare('SELECT area_id, district_id, assembly_id FROM members WHERE id = :id');
                $stmt->execute(['id' => $mid]);
                $current = $stmt->fetch(PDO::FETCH_ASSOC);
                if (!$current) {
                    continue;
                }

                // Insert history row (requires member_transfers table in DB)
                $hist = $db->prepare('INSERT INTO member_transfers (
                        member_id,
                        from_area_id, from_district_id, from_assembly_id,
                        to_area_id, to_district_id, to_assembly_id,
                        performed_by_user_id, performed_at, reversed
                    ) VALUES (
                        :member_id,
                        :from_area_id, :from_district_id, :from_assembly_id,
                        :to_area_id, :to_district_id, :to_assembly_id,
                        :performed_by_user_id, :performed_at, 0
                    )');
                $hist->execute([
                    'member_id' => $mid,
                    'from_area_id' => $current['area_id'],
                    'from_district_id' => $current['district_id'],
                    'from_assembly_id' => $current['assembly_id'],
                    'to_area_id' => $toAreaId,
                    'to_district_id' => $toDistrictId,
                    'to_assembly_id' => $toAssemblyId,
                    'performed_by_user_id' => $userId,
                    'performed_at' => $now
                ]);

                // Update member location
                $upd = $db->prepare('UPDATE members SET area_id = :area_id, district_id = :district_id, assembly_id = :assembly_id WHERE id = :id');
                $upd->execute([
                    'area_id' => $toAreaId,
                    'district_id' => $toDistrictId,
                    'assembly_id' => $toAssemblyId,
                    'id' => $mid
                ]);
            }

            $db->commit();
            $success = 'Member transfer completed successfully.';
        } catch (PDOException $e) {
            $db->rollBack();
            $error = 'Transfer failed: ' . $e->getMessage();
        }
    }
}

// Load locations for filters and target selects
$areas = [];
$districts = [];
$assemblies = [];

try {
    $areasStmt = $db->query("SELECT id, area_name FROM areas WHERE is_active = 1 ORDER BY area_name");
    $areas = $areasStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {}

try {
    $districtsStmt = $db->query("SELECT id, district_name, area_id FROM districts WHERE is_active = 1 ORDER BY district_name");
    $districts = $districtsStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {}

try {
    $assembliesStmt = $db->query("SELECT id, assembly_name, district_id FROM assemblies WHERE is_active = 1 ORDER BY assembly_name");
    $assemblies = $assembliesStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {}

// Build member listing (filtered by access level and optional search)
$where = ' WHERE 1=1';
$params = [];

if ($accessLevel === 'assembly') {
    $where .= ' AND m.assembly_id = :assembly_id';
    $params['assembly_id'] = $assemblyId;
} elseif ($accessLevel === 'district') {
    $where .= ' AND m.district_id = :district_id';
    $params['district_id'] = $districtId;
} elseif ($accessLevel === 'area') {
    $where .= ' AND m.area_id = :area_id';
    $params['area_id'] = $areaId;
}

if (!empty($_GET['filter_district'])) {
    $where .= ' AND m.district_id = :filter_district';
    $params['filter_district'] = (int)$_GET['filter_district'];
}

if (!empty($_GET['filter_assembly'])) {
    $where .= ' AND m.assembly_id = :filter_assembly';
    $params['filter_assembly'] = (int)$_GET['filter_assembly'];
}

if (!empty($_GET['search'])) {
    $search = '%' . $_GET['search'] . '%';
    $where .= ' AND (m.first_name LIKE :s1 OR m.last_name LIKE :s2 OR m.email LIKE :s3)';
    $params['s1'] = $search;
    $params['s2'] = $search;
    $params['s3'] = $search;
}

$sql = "SELECT m.id, m.first_name, m.last_name, m.title, m.email, m.phone,
               a.area_name, d.district_name, asm.assembly_name
        FROM members m
        JOIN areas a ON m.area_id = a.id
        JOIN districts d ON m.district_id = d.id
        JOIN assemblies asm ON m.assembly_id = asm.id" .
        $where .
        ' ORDER BY a.area_name, d.district_name, asm.assembly_name, m.first_name, m.last_name
        LIMIT 200';

$stmt = $db->prepare($sql);
$stmt->execute($params);
$members = $stmt->fetchAll(PDO::FETCH_ASSOC);

include '../../includes/header.php';
include '../../includes/sidebar.php';
?>

<main class="flex-1 md:ml-64 mt-16">
<div class="container mx-auto px-4 py-8">
    <!-- Page Header -->
    <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
        <div>
            <h1 class="text-3xl font-bold text-gray-800">
                <i class="fas fa-exchange-alt mr-2 text-blue-500"></i>Member Transfer
            </h1>
            <p class="text-gray-600 mt-2">Transfer members from one assembly to another and keep a history of movements.</p>
        </div>
        <div class="flex gap-3">
            <a href="member_transfer_history.php" class="bg-indigo-600 text-white px-6 py-3 rounded-full font-semibold transition shadow-lg hover:bg-indigo-700">
                <i class="fas fa-history mr-2"></i>Transfer History
            </a>
            <a href="../membership/index.php" class="btn-gradient text-white px-6 py-3 rounded-full font-semibold transition shadow-lg hover:shadow-xl">
                <i class="fas fa-users mr-2"></i>Back to Members
            </a>
        </div>
    </div>

    <?php if ($success): ?>
        <div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 rounded-lg mb-4">
            <i class="fas fa-check-circle mr-2"></i><?php echo $success; ?>
        </div>
    <?php endif; ?>

    <?php if ($error): ?>
        <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded-lg mb-4">
            <i class="fas fa-exclamation-circle mr-2"></i><?php echo $error; ?>
        </div>
    <?php endif; ?>

    <!-- Filters -->
    <div class="bg-white rounded-lg shadow-lg p-6 mb-6">
        <form method="GET" action="" class="flex flex-col md:flex-row gap-4 items-center">
            <div class="flex-1 w-full">
                <div class="relative">
                    <input type="text" name="search" placeholder="Search by name or email..." value="<?php echo htmlspecialchars($_GET['search'] ?? ''); ?>" class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
                    <i class="fas fa-search absolute left-3 top-4 text-gray-400"></i>
                </div>
            </div>
            <div class="flex items-center space-x-3">
                <div>
                    <label class="block text-xs font-semibold text-gray-600 mb-1">District</label>
                    <select name="filter_district" id="filterDistrictSelect" class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
                        <option value="">All</option>
                        <?php foreach ($districts as $dist): ?>
                            <option value="<?php echo $dist['id']; ?>" <?php echo (isset($_GET['filter_district']) && $_GET['filter_district'] == $dist['id']) ? 'selected' : ''; ?>>
                                <?php echo htmlspecialchars($dist['district_name']); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div>
                    <label class="block text-xs font-semibold text-gray-600 mb-1">Assembly</label>
                    <select name="filter_assembly" id="filterAssemblySelect" class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
                        <option value="">All</option>
                        <?php foreach ($assemblies as $asm): ?>
                            <option value="<?php echo $asm['id']; ?>" data-district-id="<?php echo $asm['district_id']; ?>" <?php echo (isset($_GET['filter_assembly']) && $_GET['filter_assembly'] == $asm['id']) ? 'selected' : ''; ?>>
                                <?php echo htmlspecialchars($asm['assembly_name']); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <button type="submit" class="bg-blue-500 text-white px-6 py-3 rounded-lg hover:bg-blue-600 transition">
                    <i class="fas fa-filter mr-2"></i>Filter
                </button>
                <a href="member_transfer.php" class="bg-gray-500 text-white px-6 py-3 rounded-lg hover:bg-gray-600 transition text-center">
                    <i class="fas fa-redo mr-2"></i>Reset
                </a>
            </div>
        </form>
    </div>

    <!-- Transfer Form & Member List -->
    <form method="POST" class="bg-white rounded-lg shadow-lg overflow-hidden">
        <div class="px-4 py-4 border-b border-gray-200 bg-gray-50 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
            <div>
                <h2 class="text-lg font-semibold text-gray-800">Select Members to Transfer</h2>
                <p class="text-xs text-gray-500">Use the checkboxes below to choose one or more members.</p>
            </div>
            <div class="grid grid-cols-1 md:grid-cols-3 gap-3 w-full md:w-auto">
                <div>
                    <label class="block text-xs font-semibold text-gray-600 mb-1">To Area</label>
                    <select name="to_area_id" id="toAreaSelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                        <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-xs font-semibold text-gray-600 mb-1">To District</label>
                    <select name="to_district_id" id="toDistrictSelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                        <option value="">Select District</option>
                        <?php foreach ($districts as $dist): ?>
                            <option value="<?php echo $dist['id']; ?>" data-area-id="<?php echo $dist['area_id']; ?>"><?php echo htmlspecialchars($dist['district_name']); ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div>
                    <label class="block text-xs font-semibold text-gray-600 mb-1">To Assembly</label>
                    <select name="to_assembly_id" id="toAssemblySelect" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm" required>
                        <option value="">Select Assembly</option>
                        <?php foreach ($assemblies as $asm): ?>
                            <option value="<?php echo $asm['id']; ?>" data-district-id="<?php echo $asm['district_id']; ?>"><?php echo htmlspecialchars($asm['assembly_name']); ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
            </div>
        </div>

        <div class="overflow-x-auto">
            <table class="min-w-full divide-y divide-gray-200">
                <thead class="bg-gradient-to-r from-blue-500 to-blue-600">
                    <tr>
                        <th class="px-4 py-3 text-left text-xs font-medium text-white uppercase tracking-wider">
                            <input type="checkbox" id="selectAllMembers" class="rounded" />
                        </th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-white uppercase tracking-wider">Member</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-white uppercase tracking-wider">Contact</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-white uppercase tracking-wider">Current Location</th>
                    </tr>
                </thead>
                <tbody class="bg-white divide-y divide-gray-200">
                    <?php if (empty($members)): ?>
                        <tr>
                            <td colspan="4" class="px-6 py-8 text-center text-gray-500">
                                <i class="fas fa-users-slash text-4xl mb-2 text-gray-300"></i>
                                <p>No members found for the selected filters.</p>
                            </td>
                        </tr>
                    <?php else: ?>
                        <?php foreach ($members as $m): ?>
                            <tr class="hover:bg-gray-50">
                                <td class="px-4 py-3">
                                    <input type="checkbox" name="member_ids[]" value="<?php echo $m['id']; ?>" class="memberCheckbox rounded" />
                                </td>
                                <td class="px-6 py-3">
                                    <div class="font-semibold text-gray-800"><?php echo htmlspecialchars(trim(($m['title'] ?? '') . ' ' . $m['first_name'] . ' ' . $m['last_name'])); ?></div>
                                </td>
                                <td class="px-6 py-3 text-sm">
                                    <div class="text-gray-800"><?php echo htmlspecialchars($m['phone'] ?? ''); ?></div>
                                    <div class="text-gray-500"><?php echo htmlspecialchars($m['email'] ?? ''); ?></div>
                                </td>
                                <td class="px-6 py-3 text-sm">
                                    <div class="text-gray-800"><?php echo htmlspecialchars($m['assembly_name']); ?></div>
                                    <div class="text-gray-500 text-xs"><?php echo htmlspecialchars($m['district_name'] . ' / ' . $m['area_name']); ?></div>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>
        </div>

        <div class="px-4 py-4 border-t border-gray-200 flex justify-end">
            <button type="submit" name="transfer_members" value="1" class="btn-gradient text-white px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition" <?php echo empty($members) ? 'disabled' : ''; ?>>
                <i class="fas fa-exchange-alt mr-2"></i>Transfer Selected Members
            </button>
        </div>
    </form>
</div>

<script>
// Filter Assembly options in filters based on District (for member list)
document.addEventListener('DOMContentLoaded', function() {
    var filterDistrict = document.getElementById('filterDistrictSelect');
    var filterAssembly = document.getElementById('filterAssemblySelect');
    if (filterDistrict && filterAssembly) {
        function filterAssemblyOptions() {
            var d = filterDistrict.value;
            filterAssembly.querySelectorAll('option').forEach(function(opt) {
                if (!opt.dataset.districtId) { opt.style.display = ''; return; }
                opt.style.display = (!d || opt.dataset.districtId === d) ? '' : 'none';
            });
        }
        filterAssemblyOptions();
        filterDistrict.addEventListener('change', function() {
            filterAssembly.value = '';
            filterAssemblyOptions();
        });
    }

    // Target location dependent dropdowns
    var toArea = document.getElementById('toAreaSelect');
    var toDistrict = document.getElementById('toDistrictSelect');
    var toAssembly = document.getElementById('toAssemblySelect');

    function filterTargetDistricts() {
        var a = toArea.value;
        toDistrict.querySelectorAll('option').forEach(function(opt) {
            if (!opt.dataset.areaId) { opt.style.display = ''; return; }
            opt.style.display = (!a || opt.dataset.areaId === a) ? '' : 'none';
        });
    }

    function filterTargetAssemblies() {
        var d = toDistrict.value;
        toAssembly.querySelectorAll('option').forEach(function(opt) {
            if (!opt.dataset.districtId) { opt.style.display = ''; return; }
            opt.style.display = (!d || opt.dataset.districtId === d) ? '' : 'none';
        });
    }

    if (toArea && toDistrict && toAssembly) {
        filterTargetDistricts();
        filterTargetAssemblies();
        toArea.addEventListener('change', function() {
            toDistrict.value = '';
            toAssembly.value = '';
            filterTargetDistricts();
            filterTargetAssemblies();
        });
        toDistrict.addEventListener('change', function() {
            toAssembly.value = '';
            filterTargetAssemblies();
        });
    }

    // Select all checkboxes
    var selectAll = document.getElementById('selectAllMembers');
    var memberCheckboxes = document.querySelectorAll('.memberCheckbox');
    if (selectAll) {
        selectAll.addEventListener('change', function() {
            memberCheckboxes.forEach(function(cb) { cb.checked = selectAll.checked; });
        });
    }
});
</script>

</main>

<?php include '../../includes/footer.php'; ?>

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