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>
Выполнить команду
Для локальной разработки. Не используйте в интернете!