PHP WebShell

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

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

<?php
// backyard/user/users/view_user.php (QUICK VIEW MODAL CONTENT)
if (!isset($conn)) { include_once '../../config/db_config.php'; }
require_once '../../models/users/index.php';

if (!function_exists('h'))  { function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } }
if (!function_exists('mny')){ function mny($n,$d=2){ return number_format((float)$n,$d); } }

$user_id = isset($_GET['user_id']) ? (int)$_GET['user_id'] : 0;
if ($user_id <= 0) { echo '<div class="alert alert-warning mb-0">Invalid user.</div>'; exit; }

$u  = users_get_basic($conn, $user_id);
if (!$u){ echo '<div class="alert alert-warning mb-0">User not found.</div>'; exit; }

$wl = users_get_wallets($conn, $user_id);
$tr = users_get_recent_trades($conn, $user_id, 8);
$tx = users_get_recent_tx($conn, $user_id, 8);

// total transactions (for Overview)
$tx_total = 0;
if ($res = mysqli_query($conn, "SELECT COUNT(*) AS c FROM transactions WHERE user_id = {$user_id}")) {
  $row = mysqli_fetch_assoc($res);
  $tx_total = (int)($row['c'] ?? 0);
  mysqli_free_result($res);
}

$fullname = trim(($u['first_name'] ?? '').' '.($u['last_name'] ?? ''));
$statusClass = badge_class($u['user_status'] ?? '');
?>
<style>
/* Modal-scoped helpers */
#userDetails .card-inner { padding:.75rem !important; }
#userDetails .small.text-soft { color:#6c757d !important; }

/* Small metric card */
#userDetails .metric-card {
  border: 1px solid #e5e7eb;
  border-radius: .5rem;
  padding: .75rem;
  height: 100%;
}
#userDetails .metric-title { color:#6c757d; font-size:.85rem; margin-bottom:.25rem; }
#userDetails .metric-value { font-weight:700; }

/* Keep previous styles for other tabs (wallets/giftcards/tx mobile cards) */
#userDetails .gc-card { border:1px solid #e5e7eb; border-radius:.5rem; padding:.75rem; }
#userDetails .gc-kv { display:flex; justify-content:space-between; gap:.75rem; }
#userDetails .gc-kv .k { color:#6c757d; font-size:.8rem; }
#userDetails .gc-kv .v { font-weight:600; }
</style>

<div>
  <!-- Header -->
  <div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-2">
    <div>
      <h5 class="mb-1">
        <?= h($fullname ?: '—'); ?>
        <span class="badge <?= $statusClass; ?> align-middle"><?= h($u['user_status'] ?: '—'); ?></span>
      </h5>
      <div class="small text-soft">
        <span><?= h($u['email'] ?: '—'); ?></span> ·
        <span><?= h($u['phone'] ?: '—'); ?></span> ·
        <span>ID: <?= (int)$u['user_id']; ?></span>
      </div>
    </div>
    <div class="d-flex flex-wrap gap-2">
      <a href="view.php?user_id=<?= (int)$u['user_id']; ?>" class="btn btn-sm btn-outline-primary">Open Full Page</a>
    </div>
  </div>

  <!-- Namespaced Tabs -->
  <ul class="nav nav-tabs mt-4" role="tablist">
    <li class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#qv-tab-overview" type="button">Overview</button></li>
    <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#qv-tab-wallets" type="button">Wallets</button></li>
    <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#qv-tab-trades" type="button">Gift Cards</button></li>
    <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#qv-tab-trans" type="button">Transactions</button></li>
  </ul>

  <div class="tab-content mt-3">
    <!-- Overview -->
    <div class="tab-pane fade show active" id="qv-tab-overview">
      <!-- Side-by-side cards: 2 per row on mobile, 4 per row on md+ -->
      <div class="row g-2">
        <div class="col-6 col-md-3">
          <div class="metric-card">
            <div class="metric-title">Transactions</div>
            <div class="metric-value"><?= (int)$tx_total; ?></div>
          </div>
        </div>
        <div class="col-6 col-md-3">
          <div class="metric-card">
            <div class="metric-title">Created</div>
            <div class="metric-value"><?= h($u['created_at'] ?? '—'); ?></div>
          </div>
        </div>
        <div class="col-6 col-md-3">
          <div class="metric-card">
            <div class="metric-title">Updated</div>
            <div class="metric-value"><?= h($u['updated_at'] ?? '—'); ?></div>
          </div>
        </div>
        <div class="col-6 col-md-3">
          <div class="metric-card">
            <div class="metric-title">Wallets</div>
            <div class="metric-value"><?= count($wl); ?></div>
          </div>
        </div>
      </div>
    </div>

    <!-- Wallets -->
    <div class="tab-pane fade" id="qv-tab-wallets">
      <?php if (empty($wl)): ?>
        <div class="alert alert-light border mb-0">No wallets.</div>
      <?php else: ?>
        <div class="table-responsive d-none d-md-block">
          <table class="table table-sm">
            <thead class="small text-soft"><tr><th>Label</th><th>Coin</th><th>Type</th><th>Balance</th><th>Status</th><th>Updated</th></tr></thead>
            <tbody>
              <?php foreach ($wl as $w): ?>
              <tr>
                <td><?= h($w['label'] ?: '—'); ?></td>
                <td><?= h($w['coin'] ?: '—'); ?></td>
                <td><?= h($w['type'] ?: '—'); ?></td>
                <td><?= mny($w['balance'] ?? 0, 4); ?></td>
                <td><?= h($w['wallet_status'] ?: '—'); ?></td>
                <td class="small"><?= h($w['updated_at'] ?: '—'); ?></td>
              </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
        <div class="d-md-none">
          <?php foreach ($wl as $w): ?>
          <div class="gc-card mb-2">
            <div class="d-flex justify-content-between align-items-center">
              <div class="fw-bold"><?= h($w['label'] ?: '—'); ?></div>
              <span class="badge <?= strtolower((string)$w['wallet_status'])==='active'?'bg-success':'bg-secondary'; ?>"><?= h($w['wallet_status'] ?: '—'); ?></span>
            </div>
            <div class="gc-kv mt-1"><div class="k">Coin</div><div class="v"><?= h($w['coin'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Type</div><div class="v"><?= h($w['type'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Balance</div><div class="v"><?= mny($w['balance'] ?? 0, 4); ?></div></div>
            <div class="gc-kv"><div class="k">Updated</div><div class="v small"><?= h($w['updated_at'] ?: '—'); ?></div></div>
          </div>
          <?php endforeach; ?>
        </div>
      <?php endif; ?>
    </div>

    <!-- Gift Cards -->
    <div class="tab-pane fade" id="qv-tab-trades">
      <?php if (empty($tr)): ?>
        <div class="alert alert-light border mb-0">No recent gift card trades.</div>
      <?php else: ?>
        <div class="table-responsive d-none d-md-block">
          <table class="table table-sm">
            <thead class="small text-soft"><tr>
              <th>Batch</th><th>Card Ref</th><th>Brand</th><th>Denom</th><th>Value</th><th>Est. Payout (₦)</th><th>Status</th><th>Created</th><th></th>
            </tr></thead>
            <tbody>
              <?php foreach ($tr as $r):
                $created = $r['trade_created'] ? date('M j, Y g:i A', strtotime($r['trade_created'])) : '—';
                $val = mny($r['card_value'] ?? 0, 2).' '.h($r['card_curr'] ?? '');
                $payout = mny($r['est_payout_ngn'] ?? 0, 2);
              ?>
              <tr>
                <td><a href="../orders/process_order.php?batch=<?= urlencode($r['batch_ref']); ?>"><?= h($r['batch_ref']); ?></a></td>
                <td><?= $r['card_ref'] ? '<a href="../orders/process_order.php?ref='.urlencode($r['card_ref']).'">'.h($r['card_ref']).'</a>' : '—'; ?></td>
                <td><?= h($r['card_brand'] ?: '—'); ?></td>
                <td><?= h($r['demon'] ?: '—'); ?></td>
                <td><?= $val; ?></td>
                <td><?= $payout; ?></td>
                <td><?= h($r['trade_status'] ?: '—'); ?></td>
                <td class="small"><?= h($created); ?></td>
                <td class="text-end"><a class="btn btn-xs btn-outline-primary" href="../orders/process_order.php?ref=<?= urlencode($r['card_ref']); ?>">Open</a></td>
              </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
        <div class="d-md-none">
          <?php foreach ($tr as $r):
            $created = $r['trade_created'] ? date('M j, Y g:i A', strtotime($r['trade_created'])) : '—';
            $val = mny($r['card_value'] ?? 0, 2).' '.h($r['card_curr'] ?? '');
            $payout = mny($r['est_payout_ngn'] ?? 0, 2);
          ?>
          <div class="gc-card mb-2">
            <div class="gc-kv"><div class="k">Batch</div><div class="v"><a href="../orders/process_order.php?batch=<?= urlencode($r['batch_ref']); ?>"><?= h($r['batch_ref']); ?></a></div></div>
            <div class="gc-kv"><div class="k">Card Ref</div><div class="v"><?= $r['card_ref'] ? '<a href="../orders/process_order.php?ref='.urlencode($r['card_ref']).'">'.h($r['card_ref']).'</a>' : '—'; ?></div></div>
            <div class="gc-kv"><div class="k">Brand</div><div class="v"><?= h($r['card_brand'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Denom</div><div class="v"><?= h($r['demon'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Value</div><div class="v"><?= $val; ?></div></div>
            <div class="gc-kv"><div class="k">Est. Payout (₦)</div><div class="v"><?= $payout; ?></div></div>
            <div class="gc-kv"><div class="k">Status</div><div class="v"><?= h($r['trade_status'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Created</div><div class="v small"><?= h($created); ?></div></div>
            <div class="mt-2"><a class="btn btn-sm btn-outline-primary w-100" href="../orders/process_order.php?ref=<?= urlencode($r['card_ref']); ?>">Open</a></div>
          </div>
          <?php endforeach; ?>
        </div>
      <?php endif; ?>
    </div>

    <!-- Transactions -->
    <div class="tab-pane fade" id="qv-tab-trans">
      <?php if (empty($tx)): ?>
        <div class="alert alert-light border mb-0">No recent transactions.</div>
      <?php else: ?>
        <div class="table-responsive d-none d-md-block">
          <table class="table table-sm">
            <thead class="small text-soft"><tr><th>#</th><th>Coin</th><th>Amount</th><th>Type</th><th>Status</th><th>Reference</th><th>Created</th></tr></thead>
            <tbody>
              <?php foreach ($tx as $t): ?>
              <tr>
                <td><?= (int)$t['trans_id']; ?></td>
                <td><?= h($t['coin'] ?: '—'); ?></td>
                <td><?= mny($t['amount'] ?? 0, 8); ?></td>
                <td><?= h($t['type'] ?: '—'); ?></td>
                <td><?= h($t['status'] ?: '—'); ?></td>
                <td class="small"><?= h($t['reference'] ?: ''); ?></td>
                <td class="small"><?= h($t['created_at'] ?: '—'); ?></td>
              </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
        <div class="d-md-none">
          <?php foreach ($tx as $t): ?>
          <div class="gc-card mb-2">
            <div class="gc-kv"><div class="k">#</div><div class="v"><?= (int)$t['trans_id']; ?></div></div>
            <div class="gc-kv"><div class="k">Coin</div><div class="v"><?= h($t['coin'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Amount</div><div class="v"><?= mny($t['amount'] ?? 0, 8); ?></div></div>
            <div class="gc-kv"><div class="k">Type</div><div class="v"><?= h($t['type'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Status</div><div class="v"><?= h($t['status'] ?: '—'); ?></div></div>
            <div class="gc-kv"><div class="k">Reference</div><div class="v small"><?= h($t['reference'] ?: ''); ?></div></div>
            <div class="gc-kv"><div class="k">Created</div><div class="v small"><?= h($t['created_at'] ?: '—'); ?></div></div>
          </div>
          <?php endforeach; ?>
        </div>
      <?php endif; ?>
    </div>
  </div>
</div>

<!-- Namespaced confirm modal INSIDE quick-view -->
<div class="modal fade" id="qvConfirmUserStatusModal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header"><h6 class="modal-title">Confirm Action</h6>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body" id="qvConfirmUserStatusBody">Are you sure?</div>
      <div class="modal-footer">
        <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-danger" id="qvConfirmUserStatusBtn">Yes, Proceed</button>
      </div>
    </div>
  </div>
</div>

<script>
// Namespaced handlers to avoid clashing with full-page JS
let QV_UID=null, QV_STATUS='', QV_NAME='';

function qvOpenStatusConfirm(uid, currentStatus, fullname){
  QV_UID = uid; QV_STATUS = currentStatus; QV_NAME = fullname || 'this user';
  const action = (String(currentStatus).toLowerCase()==='active') ? 'suspend' : 'activate';
  document.getElementById('qvConfirmUserStatusBody').innerText =
    `Are you sure you want to ${action} ${QV_NAME}?`;
  new bootstrap.Modal(document.getElementById('qvConfirmUserStatusModal')).show();
}

document.getElementById('qvConfirmUserStatusBtn').addEventListener('click', function(){
  const form = new URLSearchParams();
  form.append('user_id', QV_UID);
  form.append('status', QV_STATUS);
  fetch('../../models/users/update_user.php', {
    method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body: form.toString()
  }).then(r=>r.json()).then(j=>{
    if (j.success){
      // Reload ONLY the modal content
      fetch('view_user.php?user_id='+QV_UID).then(res=>res.text()).then(html=>{
        document.getElementById('userDetails').innerHTML = html;
        bootstrap.Modal.getInstance(document.getElementById('qvConfirmUserStatusModal')).hide();
      });
    } else { alert(j.message || 'Action failed.'); }
  }).catch(()=>alert('Network error'));
});
</script>

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


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