:: **Zploit** v1.0 | Current Path: **/home/kreativepixelz/tdrbazaar.com/crm/**
:: Editing File: lead_list.php
<?php include "header.php"; // Access control & role configurations $user_role = $_SESSION['role'] ?? 'sales'; $logged_in_user_id = $_SESSION['user_id'] ?? 0; $is_master_user = ($user_role === 'admin' || $user_role === 'master'); ?> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" /> <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css"> <style> .pagination { justify-content: center !important; } .filter-card .form-control:focus, .filter-card .form-select:focus { border-color: #86b7fe; box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); } .filter-card .input-group-text { background-color: #f8f9fa; color: #6c757d; } /* Keep Action Column sticky or easily accessible at the front */ .table-manage-leads th:nth-child(2), .table-manage-leads td:nth-child(2) { position: sticky; left: 30px; background: #fff; z-index: 2; } #manage-leads-list_previous { display:none; } #manage-leads-list_next { display:none; } </style> <div class="page-wrapper"> <div class="content pb-0"> <?php // Req 10: Master User specific restriction query logic $where_clause = "WHERE 1=1"; if (!$is_master_user) { $where_clause .= " AND is_drc_holder = 0 AND is_private_master = 0"; } else { // If master user, restrict based on assignment if required $where_clause .= " AND (is_private_master = 0 OR assigned_master_user_id = $logged_in_user_id OR $logged_in_user_id = 1)"; } $count_q = mysqli_query($conn, "SELECT COUNT(*) AS total FROM leads $where_clause"); $count_r = mysqli_fetch_assoc($count_q); $total_leads = $count_r['total']; ?> <div class="d-flex align-items-center justify-content-between gap-2 mb-4 flex-wrap"> <div> <h4 class="mb-1">Leads Directory <span class="badge badge-soft-primary ms-2"><?php echo $total_leads; ?></span></h4> <nav aria-label="breadcrumb"> <ol class="breadcrumb mb-0 p-0"> <li class="breadcrumb-item"><a href="dashboard.php">Home</a></li> <li class="breadcrumb-item active" aria-current="page">Leads Management</li> </ol> </nav> </div> <div class="gap-2 d-flex align-items-center flex-wrap"> <!-- Req 6: Bulk Selection & Delete Buttons --> <button type="button" class="btn btn-outline-secondary btn-sm" id="btnSelectAll"><i class="ti ti-check-all me-1"></i>Select All</button> <button type="button" class="btn btn-danger btn-sm d-none" id="btnBulkDelete"><i class="ti ti-trash me-1"></i>Delete Selected</button> <!-- Req 4: Add lead redirect button --> <a href="lead_add.php" class="btn btn-primary btn-sm"> <i class="ti ti-square-rounded-plus-filled me-1"></i>Add Lead </a> <div class="dropdown"> <a href="javascript:void(0);" class="dropdown-toggle btn btn-outline-light px-2 shadow" data-bs-toggle="dropdown"> <i class="ti ti-package-export me-2"></i>Export </a> <div class="dropdown-menu dropdown-menu-end"> <ul> <li><a href="#" id="exportPdf" class="dropdown-item"><i class="ti ti-file-type-pdf me-1"></i>PDF</a></li> <li><a href="#" id="exportExcel" class="dropdown-item"><i class="ti ti-file-type-xls me-1"></i>Excel</a></li> <li><a href="#" id="exportCsv" class="dropdown-item"><i class="ti ti-file-type-csv me-1"></i>CSV</a></li> </ul> </div> </div> <a href="javascript:void(0);" class="btn btn-icon btn-outline-light shadow" onclick="reloadTableData()"><i class="ti ti-refresh"></i></a> </div> </div> <!-- Filter Section --> <div class="card border-0 rounded-0 shadow-sm mb-4 filter-card"> <div class="card-body py-3"> <div class="row g-3 align-items-center"> <div class="col-12 col-md-3"> <div class="input-group input-group-sm"> <label class="input-group-text"><i class="ti ti-filter"></i></label> <select id="stageFilter" class="form-select form-select-sm fw-medium text-secondary"> <option value="">All Stages</option> <?php $stg_filter_q = mysqli_query($conn, "SELECT * FROM lead_stages ORDER BY id ASC"); while($sf = mysqli_fetch_assoc($stg_filter_q)) { echo "<option value='".htmlspecialchars($sf['name'])."'>".htmlspecialchars($sf['name'])."</option>"; } ?> </select> </div> </div> <div class="col-12 col-md-3"> <div class="input-group input-group-sm"> <label class="input-group-text"><i class="ti ti-building"></i></label> <select id="authorityFilter" class="form-select form-select-sm fw-medium text-secondary"> <option value="">All Authorities</option> <option value="PMC">PMC</option> <option value="PCMC">PCMC</option> <!-- Req 14 --> <option value="PMRDA">PMRDA</option> <!-- Req 14 --> </select> </div> </div> <div class="col-12 col-md-3"> <div class="input-group input-group-sm"> <label class="input-group-text"><i class="ti ti-flag"></i></label> <select id="priorityFilter" class="form-select form-select-sm fw-medium text-secondary"> <option value="">All Priorities</option> <option value="Hot">Hot</option> <option value="Warm">Warm</option> <option value="Cold">Cold</option> </select> </div> </div> <div class="col-12 col-md-3"> <button type="button" id="btnClearFilters" class="btn btn-sm btn-outline-danger w-100"> <i class="ti ti-refresh-dot me-1"></i> Clear Filters </button> </div> </div> </div> </div> <!-- Main Data Table Card --> <div class="card border-0 rounded-0 shadow-sm"> <div class="card-header d-flex align-items-center justify-content-between gap-2 flex-wrap"> <div class="input-icon input-icon-start position-relative"> <span class="input-icon-addon text-dark"><i class="ti ti-search"></i></span> <input type="text" id="customSearchInput" class="form-control" placeholder="Search Lead Matrix..."> </div> <div class="float:right"> <button class="btn btn-sm btn-outline-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#importCSVModal"> <i class="ti ti-file-type-csv me-1"></i> Import CSV </button> </div> </div> <div class="card-body"> <div class="table-responsive"> <table id="manage-leads-list" class="table table-hover align-middle nowrap table-manage-leads" style="width:100%"> <thead class="table-light"> <tr> <th style="width: 30px;"><input type="checkbox" id="selectAllCheckbox"></th> <!-- Req 15: Action Column Shifted to FRONT --> <th class="text-center" style="min-width: 100px;">Action</th> <th>Contact & Company</th> <!-- Req 7 & 12 --> <th>Deal Name</th> <!-- Req 9: Compulsion removed --> <th>Party Category</th> <th>Authority/Location</th> <th>Sub-Pipeline</th> <!-- Req 13 & 14 --> <th>Priority</th> <th>Closing Date</th> <th>Current Stage</th> </tr> </thead> <tbody> <?php $sql_query = "SELECT l.*, s.name as stage_name FROM leads l LEFT JOIN lead_stages s ON l.stage_id = s.id $where_clause ORDER BY l.id DESC"; $query = mysqli_query($conn, $sql_query); while($row = mysqli_fetch_assoc($query)) { $closing_f = (!empty($row['closing_date']) && $row['closing_date'] != '0000-00-00') ? date("d/m/Y", strtotime($row['closing_date'])) : 'Not Set'; $p_badge = 'bg-secondary'; if(strpos($row['deal_priority'], 'Hot') !== false) $p_badge = 'bg-danger'; if(strpos($row['deal_priority'], 'Warm') !== false) $p_badge = 'bg-warning text-dark'; ?> <tr id="lead-row-<?php echo $row['id']; ?>"> <td> <input type="checkbox" name="lead_ids[]" value="<?php echo $row['id']; ?>" class="lead-select-cb"> </td> <!-- Req 15 & 5: Edit action redirecting to external edit page directly --> <td class="text-center"> <div class="d-flex justify-content-center gap-1"> <a href="lead_edit.php?id=<?php echo $row['id']; ?>" class="btn btn-sm btn-icon btn-outline-primary" title="Edit Lead"> <i class="ti ti-edit"></i> </a> <?php if ($user_role !== 'sales') { ?> <button type="button" class="btn btn-sm btn-icon btn-outline-danger btn-delete-single" data-id="<?php echo $row['id']; ?>" title="Delete Lead"> <i class="ti ti-trash"></i> </button> <?php } ?> <a href="quotation_add.php?lead_id=<?php echo $row['id']; ?>" class="btn btn-sm btn-icon btn-outline-primary" title="Edit Lead"> <i class="ti ti-file"></i> </a> </div> </td> <!-- Req 7 & 12: Company Name & Dual Contact Fields --> <td> <div class="small fw-bold text-dark"><?php echo htmlspecialchars($row['contact_name'] ?? 'Unnamed'); ?></div> <?php if(!empty($row['company_name'])) { ?> <div class="xx-small text-primary"><i class="ti ti-building me-1"></i><?php echo htmlspecialchars($row['company_name']); ?></div> <?php } ?> <div class="text-muted xx-small"><i class="ti ti-phone me-1"></i><?php echo htmlspecialchars($row['contact_no']); ?></div> <?php if(!empty($row['contact_no_2'])) { ?> <div class="text-muted xx-small"><i class="ti ti-phone-call me-1"></i><?php echo htmlspecialchars($row['contact_no_2']); ?></div> <?php } ?> </td> <td> <a href="lead_details.php?id=<?php echo $row['id']; ?>" class="text-decoration-none fw-bold text-primary"> <?php echo htmlspecialchars($row['deal_name'] ?: 'No Deal Name'); ?> </a> </td> <td><span class="badge bg-soft-secondary text-dark"><?php echo htmlspecialchars($row['party_type']); ?></span></td> <td> <span class="fw-semibold text-primary"><?php echo htmlspecialchars($row['authority']); ?></span> <div class="text-muted small"><?php echo htmlspecialchars($row['location'] ?? 'N/A'); ?></div> </td> <!-- Req 13 & 14: Sub-Pipeline DRC & PCMC / PMRDA support --> <td><span class="badge bg-light text-dark border"><?php echo htmlspecialchars($row['sub_pipeline']); ?></span></td> <td><span class="badge <?php echo $p_badge; ?>"><?php echo htmlspecialchars($row['deal_priority']); ?></span></td> <td data-sort="<?php echo $row['closing_date']; ?>"><?php echo $closing_f; ?></td> <td> <span class="badge bg-primary text-white"><?php echo htmlspecialchars($row['stage_name'] ?? 'Unknown'); ?></span> </td> </tr> <?php } ?> </tbody> </table> </div> </div> </div> </div> <?php include "footer-heading.php"; ?> </div> <!-- Import CSV Modal --> <div class="modal fade" id="importCSVModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog"> <form action="import_leads.php" method="POST" enctype="multipart/form-data"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title fw-bold">Import Leads CSV</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <input type="file" name="csv_file" class="form-control" accept=".csv" required> <small class="text-muted mt-2 d-block">Only valid .csv format allowed.</small> </div> <div class="modal-footer"> <button class="btn btn-sm btn-light border" data-bs-dismiss="modal" type="button">Cancel</button> <button class="btn btn-sm btn-primary" type="submit">Import CSV</button> </div> </div> </form> </div> </div> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script> <script> $(document).ready(function() { // Req 1 & 17: Initialize high speed DataTable configuration with optimized pagination & search var table = $('#manage-leads-list').DataTable({ responsive: true, processing: true, pageLength: 10, lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]], order: [[8, 'desc']], columnDefs: [{ targets: [0, 1], orderable: false }] }); // Req 16 & 17: Instant search persistence without reload loops $('#customSearchInput').on('keyup input', function() { table.search(this.value).draw(); }); // Custom dropdown filter bindings $('#stageFilter').on('change', function() { table.column(9).search(this.value).draw(); }); $('#authorityFilter').on('change', function() { table.column(5).search(this.value).draw(); }); $('#priorityFilter').on('change', function() { table.column(7).search(this.value).draw(); }); $('#btnClearFilters').on('click', function() { $('#stageFilter, #authorityFilter, #priorityFilter').val(''); $('#customSearchInput').val(''); table.search('').columns().search('').draw(); }); // Checkbox bulk selection tracking $('#selectAllCheckbox').on('click', function() { var rows = table.rows({ 'search': 'applied' }).nodes(); $('input[type="checkbox"]', rows).prop('checked', this.checked); toggleBulkButton(); }); $('#btnSelectAll').on('click', function() { var isChecked = $('#selectAllCheckbox').prop('checked'); $('#selectAllCheckbox').prop('checked', !isChecked); $('.lead-select-cb').prop('checked', !isChecked); toggleBulkButton(); }); $(document).on('change', '.lead-select-cb', function() { toggleBulkButton(); }); function toggleBulkButton() { var selectedCount = $('.lead-select-cb:checked').length; if (selectedCount > 0) { $('#btnBulkDelete').removeClass('d-none').html('<i class="ti ti-trash me-1"></i>Delete Selected (' + selectedCount + ')'); } else { $('#btnBulkDelete').addClass('d-none'); } } // Req 6 & 17: AJAX-based non-reloading bulk deletion $('#btnBulkDelete').on('click', function() { var selectedIds = []; $('.lead-select-cb:checked').each(function() { selectedIds.push($(this).val()); }); if(selectedIds.length > 0 && confirm('Are you sure you want to delete ' + selectedIds.length + ' selected leads?')) { $.ajax({ url: 'lead_delete_list.php', type: 'POST', data: { action: 'bulk_delete_ajax', lead_ids: selectedIds }, success: function(response) { selectedIds.forEach(function(id) { var rowNode = $('#lead-row-' + id); table.row(rowNode).remove(); }); table.draw(false); $('#btnBulkDelete').addClass('d-none'); $('#selectAllCheckbox').prop('checked', false); } }); } }); // Req 17: Single record asynchronous row removal without page reload $(document).on('click', '.btn-delete-single', function() { var leadId = $(this).data('id'); if(confirm('Are you sure you want to drop this deal entry?')) { $.ajax({ url: 'lead_delete_list.php', type: 'POST', data: { action: 'delete_ajax', lead_id: leadId }, success: function(response) { var rowNode = $('#lead-row-' + leadId); table.row(rowNode).remove().draw(false); } }); } }); }); function reloadTableData() { location.reload(); } </script> <?php include "footer.php"; ?>