PHP WebShell

Текущая директория: /var/www/bitcardoApp/backyard/models/users

Просмотр файла: users.php

<? include '../common/header.php'; ?>
<div class="nk-content nk-content-fluid">
  <div class="container-xl wide-lg">
    <div class="nk-content-body">
      <div class="nk-block-head">
        <div class="nk-block-between-md g-4">
          <div class="nk-block-head-content">
            <h5 class="nk-block-title fw-normal">Users</h5>
            <div class="nk-block-des">
              <p>List of users!</p>
            </div>
          </div>
          <div class="nk-block-head-content">
            <ul class="nk-block-tools gx-3">
              <li><a href="#" class="btn btn-primary"><span>Add New User</span></a></li>
            </ul>
          </div>
        </div>
      </div>

      <div class="nk-block-body">
        <?php
        require '../../config/db_config.php';

        // Filters
        $search_name  = isset($_GET['name'])  ? trim($_GET['name'])  : '';
        $search_email = isset($_GET['email']) ? trim($_GET['email']) : '';
        $search_phone = isset($_GET['phone']) ? trim($_GET['phone']) : '';
        $statusFilter = isset($_GET['status']) ? $_GET['status'] : 'all';

        $page  = isset($_GET['page']) ? (int) $_GET['page'] : 1;
        $limit = 50;
        $offset = ($page - 1) * $limit;

        // Build WHERE clause (case-insensitive status)
        $where = "WHERE 1=1";
        if ($statusFilter !== 'all') {
          $safe = $conn->real_escape_string($statusFilter);
          $where .= " AND LOWER(user_status) = LOWER('{$safe}')";
        }
        if ($search_name !== '')  $where .= " AND (first_name LIKE '%".$conn->real_escape_string($search_name)."%' OR last_name LIKE '%".$conn->real_escape_string($search_name)."%')";
        if ($search_email !== '') $where .= " AND email LIKE '%".$conn->real_escape_string($search_email)."%'";
        if ($search_phone !== '') $where .= " AND phone LIKE '%".$conn->real_escape_string($search_phone)."%'";

        // Total count
        $totalQuery = "SELECT COUNT(*) AS total FROM users $where";
        $total = (int)$conn->query($totalQuery)->fetch_assoc()['total'];
        $totalPages = max(1, ceil($total / $limit));

        // Fetch users
        $sql = "SELECT * FROM users $where ORDER BY user_id DESC LIMIT $limit OFFSET $offset";
        $result = $conn->query($sql);
        ?>

        <!-- FILTER FORM -->
        <form method="GET" class="row mb-3">
          <div class="col-md-2 mb-2 mb-md-0">
            <input type="text" name="name" class="form-control" placeholder="Name" value="<?= htmlspecialchars($search_name) ?>">
          </div>
          <div class="col-md-2 mb-2 mb-md-0">
            <input type="text" name="email" class="form-control" placeholder="Email" value="<?= htmlspecialchars($search_email) ?>">
          </div>
          <div class="col-md-2 mb-2 mb-md-0">
            <input type="text" name="phone" class="form-control" placeholder="Phone" value="<?= htmlspecialchars($search_phone) ?>">
          </div>
          <div class="col-md-2 mb-2 mb-md-0">
            <select name="status" class="form-select">
              <option value="all"      <?= $statusFilter === 'all' ? 'selected' : '' ?>>All</option>
              <option value="Active"   <?= strcasecmp($statusFilter,'Active')===0 ? 'selected' : '' ?>>Active</option>
              <option value="Inactive" <?= strcasecmp($statusFilter,'Inactive')===0 ? 'selected' : '' ?>>Suspended</option>
            </select>
          </div>
          <div class="col-md-4 d-flex justify-content-start">
            <button type="submit" class="btn btn-success me-2">Filter</button>
            <a href="users.php" class="btn btn-outline-secondary">Reset</a>
          </div>
        </form>

        <!-- USERS TABLE -->
        <form id="batchSuspendForm">
          <div class="table-responsive">
            <table class="table table-striped">
              <thead>
                <tr>
                  <th><input type="checkbox" id="selectAll"></th>
                  <th>S/N</th>
                  <th>First Name</th>
                  <th>Last Name</th>
                  <th>Phone</th>
                  <th>Email</th>
                  <th class="text-center">Status</th>
                  <th class="text-center">Action</th>
                </tr>
              </thead>
              <tbody>
                <?php $sn = $offset + 1; while ($row = $result->fetch_assoc()): ?>
                <tr>
                  <td><input type="checkbox" name="selected_users[]" value="<?= $row['user_id'] ?>"></td>
                  <td><?= $sn++ ?></td>
                  <td><?= htmlspecialchars($row['first_name']) ?></td>
                  <td><?= htmlspecialchars($row['last_name']) ?></td>
                  <td><?= htmlspecialchars($row['phone']) ?></td>
                  <td><?= htmlspecialchars($row['email']) ?></td>
                  <td class="text-center">
                    <?php if (strcasecmp($row['user_status'], 'active') === 0): ?>
                      <span class="badge bg-success">Active</span>
                    <?php else: ?>
                      <span class="badge bg-danger">Inactive</span>
                    <?php endif; ?>
                  </td>
                  <td class="text-center">
                    <!-- View goes to full page now -->
                    <a class="btn btn-sm btn-dark py-0 px-1" href="view.php?user_id=<?= (int)$row['user_id']; ?>">View</a>
                    &nbsp;
                    <button type="button"
                            class="btn btn-sm py-0 px-1 toggle-btn <?= (strcasecmp($row['user_status'], 'active')===0) ? 'btn-danger' : 'btn-success' ?>"
                            data-id="<?= $row['user_id'] ?>"
                            data-status="<?= htmlspecialchars($row['user_status']) ?>">
                        <?= (strcasecmp($row['user_status'], 'active')===0) ? 'Suspend' : 'Activate' ?>
                    </button>
                  </td>
                </tr>
                <?php endwhile; ?>
              </tbody>
            </table>
          </div>
        </form>

        <!-- PAGINATION -->
        <nav>
          <ul class="pagination center">
            <?php for ($i = 1; $i <= $totalPages; $i++): ?>
              <li class="page-item <?= $i == $page ? 'active' : '' ?>">
                <a class="page-link"
                   href="?page=<?= $i ?>&name=<?= urlencode($search_name) ?>&email=<?= urlencode($search_email) ?>&phone=<?= urlencode($search_phone) ?>&status=<?= urlencode($statusFilter) ?>">
                  <?= $i ?>
                </a>
              </li>
            <?php endfor; ?>
          </ul>
        </nav>

      </div>
    </div>
  </div>
</div>

<!-- CONFIRMATION MODAL (kept for suspend/activate) -->
<div class="modal fade" id="confirmActionModal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Confirm Action</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body" id="confirmModalBody">
        Are you sure you want to proceed?
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" id="confirmActionBtn" class="btn btn-danger">Yes, Proceed</button>
      </div>
    </div>
  </div>
</div>

<!-- SUCCESS MESSAGE -->
<div id="successAlert" class="alert alert-success mt-2 d-none" role="alert"></div>

<script>
let pendingUserId = null;
let pendingUserName = '';
let pendingAction = '';
let pendingUserStatus = '';

// Suspend/Activate user with confirmation modal
document.querySelectorAll('.toggle-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    pendingUserId = btn.dataset.id;
    pendingUserStatus = btn.dataset.status;

    const row = btn.closest('tr');
    const firstName = row.children[2].innerText;
    const lastName = row.children[3].innerText;
    pendingUserName = `${firstName} ${lastName}`;
    pendingAction = (pendingUserStatus.toLowerCase() === 'active') ? 'suspend' : 'activate';

    document.getElementById('confirmModalBody').innerText =
      `Are you sure you want to ${pendingAction} ${pendingUserName}?`;

    new bootstrap.Modal(document.getElementById('confirmActionModal')).show();
  });
});

// Confirm button in modal
document.getElementById('confirmActionBtn').addEventListener('click', () => {
  fetch('../../models/users/update_user.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: `user_id=${pendingUserId}&status=${encodeURIComponent(pendingUserStatus)}`
  })
  .then(res => res.json())
  .then(data => {
      if (data.success) {
          document.getElementById('successAlert').innerText =
              `${pendingUserName} was ${(data.new_status && data.new_status.toLowerCase() === 'inactive') ? 'suspended' : 'activated'} successfully.`;
          document.getElementById('successAlert').classList.remove('d-none');
          setTimeout(() => location.reload(), 1200);
      } else {
          alert('Failed to update user');
      }
  });
});

// Select all checkboxes
document.getElementById('selectAll').addEventListener('change', function () {
  document.querySelectorAll('input[name="selected_users[]"]').forEach(cb => cb.checked = this.checked);
});

// Batch suspend users
document.getElementById('batchSuspendForm').addEventListener('submit', function (e) {
  e.preventDefault();

  const selected = Array.from(this.querySelectorAll('input[name="selected_users[]"]:checked')).map(cb => cb.value);
  if (selected.length === 0) return alert('Select at least one user.');

  if (!confirm('Suspend selected users?')) return;

  fetch('../../models/users/update_user.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ batch_suspend: true, user_ids: selected })
  })
  .then(res => res.json())
  .then(data => {
      if (data.success) location.reload();
      else alert('Failed to suspend users.');
  });
});
</script>

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

Выполнить команду


Для локальной разработки. Не используйте в интернете!