- 134-tool registry with programmatic SEO (unique titles/H1/descriptions, JSON-LD graphs, sitemap index, canonical 301 enforcement via required filter) - DB-backed job queue (SKIP LOCKED) with drivers: Ffmpeg, Images (GD), Pdf (qpdf/gs/poppler), Youtube (thumbnails), Qr (server-side PNG) - Security: SSRF guard, MIME validation, rate limits, API-key auth, bcrypt admin login, security headers - Admin panel: dashboard, tools/categories/guides CRUD, SEO audit, analytics, job inspector with retry, system health, feature flags - Docker deployment (nginx + web/api FPM pools + scalable workers), PHPUnit suite (19 tests / 1139 assertions), PWA manifest + service worker
44 lines
2.0 KiB
PHP
44 lines
2.0 KiB
PHP
<?= view('partials/admin_nav') ?>
|
|
<h1 style="font-size:1.7rem;letter-spacing:-.02em;margin-bottom:1.2rem">Platform overview</h1>
|
|
<div class="grid cols-4" style="margin-bottom:1.6rem">
|
|
<?php
|
|
$stats = [
|
|
['Tools', $toolCount, '/admin/tools'],
|
|
['Guides', $guideCount, '/admin/guides'],
|
|
['Queued jobs', $queued, '/admin/jobs?status=queued'],
|
|
['Processing', $processing, '/admin/jobs?status=processing'],
|
|
];
|
|
foreach ($stats as [$label, $value, $href]): ?>
|
|
<a class="card" href="<?= esc($href) ?>">
|
|
<p style="font-size:.8rem;text-transform:uppercase;letter-spacing:.06em"><?= esc($label) ?></p>
|
|
<h2 style="font-size:2rem;font-weight:800;margin:.2rem 0 0"><?= (int) $value ?></h2>
|
|
</a>
|
|
<?php endforeach ?>
|
|
</div>
|
|
<div class="grid cols-2">
|
|
<div class="card">
|
|
<h3>Today</h3>
|
|
<p><?= number_format($viewsToday) ?> tool views · <?= number_format($startsToday) ?> jobs started · <?= (int) $failedToday ?> failed</p>
|
|
</div>
|
|
<div class="card">
|
|
<h3>Recent searches</h3>
|
|
<?php if ($searches === []): ?><p class="hint">No searches yet.</p><?php else: ?>
|
|
<ul style="margin:.3rem 0;padding-left:1.2rem">
|
|
<?php foreach ($searches as $s): $meta = json_decode((string) ($s['meta'] ?? '{}'), true); ?>
|
|
<li><?= esc($meta['term'] ?? '?') ?></li>
|
|
<?php endforeach ?>
|
|
</ul><?php endif ?>
|
|
</div>
|
|
</div>
|
|
<div class="card" style="margin-top:1rem">
|
|
<h3>Latest jobs</h3>
|
|
<table style="width:100%;font-size:.85rem;border-collapse:collapse">
|
|
<tr style="text-align:left;color:var(--ink-500)"><th>Job</th><th>Operation</th><th>Status</th><th>Created</th></tr>
|
|
<?php foreach ($recentJobs as $j): ?>
|
|
<tr><td><code><?= esc(substr($j['id'],0,8)) ?></code></td><td><?= esc($j['operation']) ?></td>
|
|
<td><span class="badge" style="<?= $j['status']==='completed'?'background:#ecfdf5;color:#047857':($j['status']==='failed'?'background:#fef2f2;color:#b91c1c':'') ?>"><?= esc($j['status']) ?></span></td>
|
|
<td><?= esc($j['created_at']) ?></td></tr>
|
|
<?php endforeach ?>
|
|
</table>
|
|
</div>
|