106 lines
4.1 KiB
PHP
106 lines
4.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/app.php';
|
|
|
|
ensure_kyc_table();
|
|
|
|
$stmt = db()->query('SELECT * FROM kyc_applications ORDER BY created_at DESC LIMIT 50');
|
|
$items = $stmt->fetchAll();
|
|
|
|
$pendingCount = 0;
|
|
foreach ($items as $row) {
|
|
if (($row['status'] ?? '') === 'pending') {
|
|
$pendingCount++;
|
|
}
|
|
}
|
|
|
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
|
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|
?>
|
|
<!doctype html>
|
|
<html lang="<?= h($lang) ?>">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title><?= h(t('admin_title')) ?> · <?= h(t('site_name')) ?></title>
|
|
<?php if ($projectDescription): ?>
|
|
<meta name="description" content="<?= h($projectDescription) ?>" />
|
|
<meta property="og:description" content="<?= h($projectDescription) ?>" />
|
|
<meta property="twitter:description" content="<?= h($projectDescription) ?>" />
|
|
<?php endif; ?>
|
|
<?php if ($projectImageUrl): ?>
|
|
<meta property="og:image" content="<?= h($projectImageUrl) ?>" />
|
|
<meta property="twitter:image" content="<?= h($projectImageUrl) ?>" />
|
|
<?php endif; ?>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?= h((string) time()) ?>">
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand-lg navbar-light">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="<?= h(url_with_lang('index.php')) ?>"><?= h(t('site_name')) ?></a>
|
|
<div class="ms-auto lang-toggle btn-group" role="group">
|
|
<a class="btn btn-sm <?= $lang === 'zh' ? 'active' : '' ?>" href="<?= h(url_with_lang('admin_kyc_list.php', ['lang' => 'zh'])) ?>">中文</a>
|
|
<a class="btn btn-sm <?= $lang === 'en' ? 'active' : '' ?>" href="<?= h(url_with_lang('admin_kyc_list.php', ['lang' => 'en'])) ?>">EN</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<main class="container my-5">
|
|
<div class="section-card">
|
|
<div class="d-flex flex-column flex-lg-row justify-content-between gap-3 mb-3">
|
|
<div>
|
|
<h1 class="section-title mb-1"><?= h(t('admin_title')) ?></h1>
|
|
<p class="text-muted mb-0"><?= h(t('admin_subtitle')) ?></p>
|
|
</div>
|
|
<div class="section-card py-2 px-3 align-self-start">
|
|
<div class="text-muted small">Pending</div>
|
|
<div class="fw-semibold"><?= h((string) $pendingCount) ?></div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!$items): ?>
|
|
<div class="alert alert-warning"><?= h(t('admin_empty')) ?></div>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Name</th>
|
|
<th>Email</th>
|
|
<th>Status</th>
|
|
<th>Submitted</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($items as $row): ?>
|
|
<?php
|
|
$statusClass = match ($row['status']) {
|
|
'approved' => 'status-approved',
|
|
'rejected' => 'status-rejected',
|
|
default => 'status-pending',
|
|
};
|
|
?>
|
|
<tr>
|
|
<td><?= h((string) $row['id']) ?></td>
|
|
<td><?= h($row['full_name']) ?></td>
|
|
<td><?= h($row['email']) ?></td>
|
|
<td><span class="status-pill <?= h($statusClass) ?>"><?= h($row['status']) ?></span></td>
|
|
<td><?= h($row['created_at']) ?></td>
|
|
<td><a class="ghost-btn text-decoration-none" href="<?= h(url_with_lang('admin_kyc_view.php', ['id' => $row['id']])) ?>"><?= h(t('admin_view')) ?></a></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</main>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/main.js?v=<?= h((string) time()) ?>"></script>
|
|
</body>
|
|
</html>
|