PHP WebShell
Текущая директория: /var/www/bitcardoApp/backyard/user/transactions
Просмотр файла: index.php
<?php
// backyard/user/transactions/index.php
include '../common/header.php';
if (!isset($conn)) {
include_once '../../config/db_config.php';
}
require_once '../../models/transactions/index.php';
date_default_timezone_set('Africa/Lagos');
// helpers (scoped)
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
function moneyx($n,$d=10){ return number_format((float)$n,$d); }
// read filters
$filters = [
'coin' => $_GET['coin'] ?? '',
'type' => $_GET['type'] ?? '',
'status' => $_GET['status'] ?? '',
'applied' => $_GET['applied'] ?? '',
'wallet_id' => $_GET['wallet_id'] ?? '',
'txid' => $_GET['txid'] ?? '',
'reference' => $_GET['reference'] ?? '',
'from' => $_GET['from'] ?? '',
'to' => $_GET['to'] ?? '',
'user_q' => $_GET['user_q'] ?? '',
'page' => (int)($_GET['page'] ?? 1),
'per_page' => (int)($_GET['per_page'] ?? 25),
];
$coins = tx_list_coins($conn);
$types = tx_list_types($conn);
$statuses = tx_list_statuses($conn);
$result = tx_search($conn, $filters);
function qurl(array $add=[]){
$qs = array_merge($_GET, $add);
return '?' . http_build_query($qs);
}
?>
<style>
/* mobile-first */
.txs-filter-toggle { display:inline-flex; align-items:center; gap:.4rem; }
@media (min-width: 768px){
.txs-filter-collapse{ display:block !important; height:auto !important; }
}
.badge-status { text-transform: capitalize; }
.dt-pair { display:flex; gap:.5rem; }
.dt-pair .k { min-width:120px; color:#6c757d; }
.dt-note { min-height:112px; }
</style>
<div class="nk-content nk-content-fluid mt-5">
<div class="container-xl wide-lg">
<div class="nk-content-body">
<div class="nk-block-head">
<div class="nk-block-between-md g-3 align-items-center">
<div class="nk-block-head-content">
<h4 class="nk-block-title fw-normal mb-1">Transactions</h4>
<p class="text-soft mb-0">“Wallet ID / Txid / Ref / Note” removed from rows; use <strong>View More</strong> to see details and edit note.</p>
</div>
<div class="nk-block-head-content">
<a href="../dashboard/index.php" class="btn btn-outline-secondary d-none d-md-inline-flex"><span>Back to Dashboard</span></a>
<a href="../dashboard/index.php" class="btn btn-outline-secondary d-md-none btn-sm"><span>Back</span></a>
</div>
</div>
</div>
<!-- Filters -->
<div class="nk-block">
<div class="card card-bordered">
<div class="card-inner">
<div class="d-flex justify-content-between align-items-center d-md-none mb-2">
<button class="btn btn-light btn-sm txs-filter-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#txFilters">
<em class="icon ni ni-filter"></em><span>Show Filters</span>
</button>
</div>
<div id="txFilters" class="collapse txs-filter-collapse">
<form class="row g-2" method="get">
<div class="col-6 col-md-2">
<label class="form-label small">Coin</label>
<select name="coin" class="form-select">
<option value="">Any</option>
<?php foreach ($coins as $c): ?>
<option value="<?= h($c); ?>" <?= $filters['coin']===$c?'selected':''; ?>><?= h($c); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label small">Type</label>
<select name="type" class="form-select">
<option value="">Any</option>
<?php foreach ($types as $t): ?>
<option value="<?= h($t); ?>" <?= $filters['type']===$t?'selected':''; ?>><?= h($t); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label small">Status</label>
<select name="status" class="form-select">
<option value="">Any</option>
<?php foreach ($statuses as $s): ?>
<option value="<?= h($s); ?>" <?= $filters['status']===$s?'selected':''; ?>><?= h($s); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-6 col-md-2">
<label class="form-label small">From</label>
<input type="date" name="from" class="form-control" value="<?= h($filters['from']); ?>">
</div>
<div class="col-6 col-md-2">
<label class="form-label small">To</label>
<input type="date" name="to" class="form-control" value="<?= h($filters['to']); ?>">
</div>
<div class="col-6 col-md-3">
<label class="form-label small">User (name/email/phone)</label>
<input type="text" name="user_q" class="form-control" value="<?= h($filters['user_q']); ?>">
</div>
<div class="col-6 col-md-2">
<label class="form-label small">Per Page</label>
<select name="per_page" class="form-select">
<?php foreach ([25,50,100,200] as $pp): ?>
<option value="<?= $pp; ?>" <?= ($filters['per_page']===$pp?'selected':''); ?>><?= $pp; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-3 d-flex align-items-end justify-content-end mt-1">
<a href="index.php" class="btn btn-outline-secondary me-2 w-50 w-md-auto">Reset</a>
<button class="btn btn-primary w-50 w-md-auto">Apply</button>
</div>
</form>
</div><!-- /collapse -->
</div>
</div>
</div>
<!-- Results -->
<div class="nk-block">
<div class="card card-bordered">
<div class="card-inner">
<!-- Mobile list -->
<div class="d-md-none">
<?php if (empty($result['rows'])): ?>
<div class="alert alert-light border mb-0">No transactions found.</div>
<?php else: ?>
<div class="gy-2">
<?php foreach ($result['rows'] as $r):
$fullname = trim(($r['first_name'] ?? '').' '.($r['last_name'] ?? ''));
$created = $r['created_at'] ? date('M j, Y g:i A', strtotime($r['created_at'])) : '—';
?>
<div class="border rounded-3 p-3 mb-2">
<div class="d-flex justify-content-between">
<div class="fw-semibold"><?= h($r['coin']); ?> • <?= h($r['type']); ?></div>
<span class="badge bg-light text-dark badge-status"><?= h($r['status']); ?></span>
</div>
<div class="small text-soft"><?= h($created); ?></div>
<div class="row g-1 mt-2">
<div class="col-6">
<div class="small text-soft">Amount</div>
<div class="fw-semibold"><?= moneyx($r['amount'] ?? 0, 10); ?></div>
</div>
<div class="col-6">
<div class="small text-soft">User</div>
<div class="fw-semibold"><?= h($fullname ?: '—'); ?></div>
<div class="text-soft small"><?= h($r['email'] ?: $r['phone'] ?: ''); ?></div>
</div>
</div>
<div class="d-flex gap-2 mt-3 mb-1">
<!-- Mobile card button -->
<button
type="button"
class="btn btn-sm btn-outline-primary w-100 py-2 btn-view-more"
data-bs-toggle="modal"
data-bs-target="#viewMoreModal"
data-id="<?= (int)$r['trans_id']; ?>"
data-created="<?= h($created); ?>"
data-coin="<?= h($r['coin']); ?>"
data-type="<?= h($r['type']); ?>"
data-amount="<?= moneyx($r['amount'] ?? 0, 10); ?>"
data-user="<?= h($fullname ?: '—'); ?>"
data-email="<?= h($r['email'] ?? ''); ?>"
data-phone="<?= h($r['phone'] ?? ''); ?>"
data-status="<?= h($r['status']); ?>"
data-wallet="<?= h($r['wallet_id'] ?? ''); ?>"
data-txid="<?= h($r['txid'] ?? ''); ?>"
data-ref="<?= h($r['reference'] ?? ''); ?>"
data-provider="<?= h($r['provider'] ?? ''); ?>"
data-note="<?= h($r['note'] ?? ''); ?>"
>View More</button>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<!-- Desktop table -->
<div class="table-responsive d-none d-md-block">
<table class="table table-striped">
<thead class="small text-soft">
<tr>
<th>ID</th>
<th>Created</th>
<th>Coin</th>
<th>Type</th>
<th>Amount</th>
<th>User</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($result['rows'])): ?>
<tr><td colspan="8" class="text-center text-muted py-4">No transactions found.</td></tr>
<?php else: ?>
<?php foreach ($result['rows'] as $r):
$fullname = trim(($r['first_name'] ?? '').' '.($r['last_name'] ?? ''));
$created = $r['created_at'] ? date('M j, Y g:i A', strtotime($r['created_at'])) : '—';
?>
<tr>
<td><?= (int)$r['trans_id']; ?></td>
<td class="small"><?= h($created); ?></td>
<td><?= h($r['coin']); ?></td>
<td><?= h($r['type']); ?></td>
<td><?= moneyx($r['amount'] ?? 0, 10); ?></td>
<td class="small">
<div class="fw-semibold"><?= h($fullname ?: '—'); ?></div>
<div class="text-soft"><?= h($r['email'] ?: $r['phone'] ?: ''); ?></div>
</td>
<td><span class="badge bg-light text-dark badge-status"><?= h($r['status']); ?></span></td>
<td class="small">
<!-- Desktop table button -->
<button
type="button"
class="btn btn-xs btn-outline-primary btn-view-more"
data-bs-toggle="modal"
data-bs-target="#viewMoreModal"
data-id="<?= (int)$r['trans_id']; ?>"
data-created="<?= h($created); ?>"
data-coin="<?= h($r['coin']); ?>"
data-type="<?= h($r['type']); ?>"
data-amount="<?= moneyx($r['amount'] ?? 0, 10); ?>"
data-user="<?= h($fullname ?: '—'); ?>"
data-email="<?= h($r['email'] ?? ''); ?>"
data-phone="<?= h($r['phone'] ?? ''); ?>"
data-status="<?= h($r['status']); ?>"
data-wallet="<?= h($r['wallet_id'] ?? ''); ?>"
data-txid="<?= h($r['txid'] ?? ''); ?>"
data-ref="<?= h($r['reference'] ?? ''); ?>"
data-provider="<?= h($r['provider'] ?? ''); ?>"
data-note="<?= h($r['note'] ?? ''); ?>"
>View More</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- Pagination -->
<?php if ($result['pages'] > 1): ?>
<div class="mt-3 d-flex justify-content-between align-items-center">
<div class="small text-soft">Page <?= (int)$result['page']; ?> of <?= (int)$result['pages']; ?> • <?= number_format($result['total']); ?> total</div>
<ul class="pagination pagination-sm mb-0">
<?php
$p = $result['page']; $pages = $result['pages'];
$prev = max(1, $p-1); $next = min($pages, $p+1);
?>
<li class="page-item <?= $p<=1?'disabled':''; ?>">
<a class="page-link" href="<?= qurl(['page'=>1]); ?>">« First</a>
</li>
<li class="page-item <?= $p<=1?'disabled':''; ?>">
<a class="page-link" href="<?= qurl(['page'=>$prev]); ?>">‹ Prev</a>
</li>
<li class="page-item disabled"><span class="page-link"><?= $p; ?></span></li>
<li class="page-item <?= $p>=$pages?'disabled':''; ?>">
<a class="page-link" href="<?= qurl(['page'=>$next]); ?>">Next ›</a>
</li>
<li class="page-item <?= $p>=$pages?'disabled':''; ?>">
<a class="page-link" href="<?= qurl(['page'=>$pages]); ?>">Last »</a>
</li>
</ul>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- View More Modal (with note editor) -->
<!-- View More Modal -->
<div class="modal fade" id="viewMoreModal" tabindex="-1" aria-labelledby="viewMoreLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title" id="viewMoreLabel">Transaction Details</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-6"><div class="small text-soft">Trans ID</div><div id="m-trans-id" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">Created</div><div id="m-created" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">Coin</div><div id="m-coin" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">Type</div><div id="m-type" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">Amount</div><div id="m-amount" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">Status</div><div id="m-status" class="fw-bold">—</div></div>
<div class="col-12"><hr></div>
<div class="col-6"><div class="small text-soft">Wallet ID</div><div id="m-wallet" class="fw-bold">—</div></div>
<div class="col-6"><div class="small text-soft">TXID</div><div id="m-txid" class="fw-bold text-break">—</div></div>
<div class="col-6"><div class="small text-soft">Reference</div><div id="m-ref" class="fw-bold text-break">—</div></div>
<div class="col-6"><div class="small text-soft">Provider</div><div id="m-provider" class="fw-bold">—</div></div>
<div class="col-12"><div class="small text-soft">Note</div><div id="m-note" class="fw-bold text-break">—</div></div>
<div class="col-12"><hr></div>
<div class="col-6"><div class="small text-soft">User</div><div id="m-user" class="fw-bold">—</div></div>
<div class="col-6">
<div class="small text-soft">Contact</div>
<div id="m-email" class="fw-bold small">—</div>
<div id="m-phone" class="fw-bold small">—</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
(function(){
function setTxt(id, val){ var el=document.getElementById(id); if(el) el.textContent = val || '—'; }
document.addEventListener('click', function(ev){
var btn = ev.target.closest('.btn-view-more');
if(!btn) return;
// Fill fields
setTxt('m-trans-id', btn.getAttribute('data-id'));
setTxt('m-created', btn.getAttribute('data-created'));
setTxt('m-coin', btn.getAttribute('data-coin'));
setTxt('m-type', btn.getAttribute('data-type'));
setTxt('m-amount', btn.getAttribute('data-amount'));
setTxt('m-status', btn.getAttribute('data-status'));
setTxt('m-wallet', btn.getAttribute('data-wallet'));
setTxt('m-txid', btn.getAttribute('data-txid'));
setTxt('m-ref', btn.getAttribute('data-ref'));
setTxt('m-provider', btn.getAttribute('data-provider'));
setTxt('m-note', btn.getAttribute('data-note'));
setTxt('m-user', btn.getAttribute('data-user'));
setTxt('m-email', btn.getAttribute('data-email'));
setTxt('m-phone', btn.getAttribute('data-phone'));
// Always try to open modal programmatically
try {
var modalEl = document.getElementById('viewMoreModal');
if (modalEl) {
var m = bootstrap.Modal.getOrCreateInstance(modalEl);
m.show();
} else {
console.error('viewMoreModal not found in DOM.');
}
} catch(e){
console.error('Bootstrap modal JS missing?', e);
}
});
})();
</script>
<?php include '../common/footer.php'; ?>
Выполнить команду
Для локальной разработки. Не используйте в интернете!