Files
MyKeyser/admin/index.php
T
Ty Clifford 25327e3302 - [index.php](/Users/tyemeclifford/Documents/GH/MyKeyser/index.php): events now appear before featured businesses, plus forum pretty-route fallback.
[events.php](/Users/tyemeclifford/Documents/GH/MyKeyser/events.php) and 
[admin/events.php](/Users/tyemeclifford/Documents/GH/MyKeyser/admin/events.php): 
event image uploads.
[menu.php](/Users/tyemeclifford/Documents/GH/MyKeyser/menu.php), 
[admin/menus.php](/Users/tyemeclifford/Documents/GH/MyKeyser/admin/menus.php), 
and 
[business.php](/Users/tyemeclifford/Documents/GH/MyKeyser/business.php): 
one configurable menu item image slot.
[account.php](/Users/tyemeclifford/Documents/GH/MyKeyser/account.php): 
circular avatar upload and crop controls.
[forum.php](/Users/tyemeclifford/Documents/GH/MyKeyser/forum.php), 
[admin/forum.php](/Users/tyemeclifford/Documents/GH/MyKeyser/admin/forum.php), 
[.htaccess](/Users/tyemeclifford/Documents/GH/MyKeyser/.htaccess), and 
[forum/index.php](/Users/tyemeclifford/Documents/GH/MyKeyser/forum/index.php): 
forum, categories, topic/reply uploads, permalinks, toggle/moderation.
[includes/db.php](/Users/tyemeclifford/Documents/GH/MyKeyser/includes/db.php) 
and 
[includes/functions.php](/Users/tyemeclifford/Documents/GH/MyKeyser/includes/functions.php): 
schema upgrades and shared upload/image helpers.
[assets/css/style.css](/Users/tyemeclifford/Documents/GH/MyKeyser/assets/css/style.css): 
neon styling for forum, images, avatars, attachments.
2026-06-19 10:49:48 -04:00

230 lines
9.7 KiB
PHP

<?php
$adminTitle = 'Dashboard';
include __DIR__.'/admin_header.php';
$stats = [
'Businesses' => qval("SELECT COUNT(*) FROM businesses WHERE is_active=1"),
'Users' => qval("SELECT COUNT(*) FROM users"),
'Reviews' => qval("SELECT COUNT(*) FROM reviews"),
'Events' => qval("SELECT COUNT(*) FROM events WHERE status='approved'"),
'Pending Events' => qval("SELECT COUNT(*) FROM events WHERE status='pending'"),
'Pending Claims' => qval("SELECT COUNT(*) FROM business_claim_requests WHERE status='pending'"),
'Pending Edits' => qval("SELECT COUNT(*) FROM business_edit_requests WHERE status='pending'"),
'Forum Topics' => qval("SELECT COUNT(*) FROM forum_topics"),
'Open Reports' => qval("SELECT COUNT(*) FROM reports WHERE status='open'"),
'Active Alerts' => qval("SELECT COUNT(*) FROM alerts WHERE is_active=1"),
];
$recentBiz = qall("SELECT * FROM businesses ORDER BY created_at DESC LIMIT 5");
$recentUsers = qall("SELECT * FROM users ORDER BY created_at DESC LIMIT 5");
$pendingEvts = qall("SELECT e.*,u.username FROM events e LEFT JOIN users u ON u.id=e.submitted_by WHERE e.status='pending' ORDER BY e.created_at DESC LIMIT 5");
$openReports = qall("SELECT r.*,b.name biz,u.username reporter FROM reports r JOIN businesses b ON b.id=r.business_id JOIN users u ON u.id=r.user_id WHERE r.status='open' ORDER BY r.created_at DESC LIMIT 5");
$pendingClaims = qall("
SELECT bcr.*, b.name biz_name, b.slug biz_slug, u.username, u.email
FROM business_claim_requests bcr
JOIN businesses b ON b.id = bcr.business_id
JOIN users u ON u.id = bcr.user_id
WHERE bcr.status = 'pending'
ORDER BY bcr.created_at DESC
LIMIT 10
");
$pendingEdits = qall("
SELECT ber.*, b.name biz_name, b.slug biz_slug, b.id biz_id, u.username
FROM business_edit_requests ber
JOIN businesses b ON b.id = ber.business_id
JOIN users u ON u.id = ber.user_id
WHERE ber.status = 'pending'
ORDER BY ber.created_at DESC
LIMIT 10
");
$recentForumTopics = qall("
SELECT ft.*, fc.name category_name, u.username,
(SELECT COUNT(*) FROM forum_replies fr WHERE fr.topic_id=ft.id) reply_count
FROM forum_topics ft
JOIN forum_categories fc ON fc.id=ft.category_id
JOIN users u ON u.id=ft.user_id
ORDER BY datetime(ft.updated_at) DESC
LIMIT 5
");
?>
<?php adminTitle('Site Overview','Welcome to the Discover Keyser WV administration panel.') ?>
<div class="stat-cards">
<?php foreach($stats as $lbl=>$val): ?>
<div class="stat-card">
<div class="sc-n" style="<?=($lbl==='Pending Edits'||$lbl==='Pending Claims')&&$val>0?'color:var(--gold)':($lbl==='Open Reports'&&$val>0?'color:var(--red-l)':'')?>">
<?=$val?>
</div>
<div class="sc-l"><?=e($lbl)?></div>
</div>
<?php endforeach; ?>
</div>
<!-- Pending owner claims — verification queue -->
<?php if ($pendingClaims): ?>
<div style="margin-bottom:2rem">
<div class="admin-sec-title" style="color:var(--gold)">
🔑 BUSINESS PAGE CLAIM REQUESTS (<?=count($pendingClaims)?>)
</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>BUSINESS</th><th>REQUESTED BY</th><th>CONTACT PHONE</th><th>SUBMITTED</th><th></th></tr></thead>
<tbody>
<?php foreach ($pendingClaims as $claim): ?>
<tr>
<td><a href="/business.php?slug=<?=e($claim['biz_slug'])?>" target="_blank" class="td-name"><?=e($claim['biz_name'])?></a></td>
<td>
<div class="td-name"><?=e($claim['username'])?></div>
<?php if ($claim['email']): ?><div style="font-size:.76rem;color:var(--text-d)"><?=e($claim['email'])?></div><?php endif; ?>
</td>
<td style="font-size:.86rem;color:var(--text)"><?=e($claim['contact_phone'])?></td>
<td style="font-size:.78rem;color:var(--text-d)"><?=ago($claim['created_at'] ?? '')?></td>
<td><a href="/admin/owners.php#claims" class="btn btn-xs btn-primary">Verify</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
<!-- Pending owner edits — top priority -->
<?php if ($pendingEdits): ?>
<div style="margin-bottom:2rem">
<div class="admin-sec-title" style="color:var(--gold)">
✏️ PENDING OWNER EDIT REQUESTS (<?=count($pendingEdits)?>)
</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>BUSINESS</th><th>FIELD</th><th>SUBMITTED BY</th><th>PROPOSED VALUE</th><th>SUBMITTED</th><th></th></tr></thead>
<tbody>
<?php
$fieldLabels = ['description'=>'Description','address'=>'Address','phone'=>'Phone',
'email'=>'Email','website'=>'Website','video_url'=>'Video','hours'=>'Hours','is_active'=>'Status'];
foreach ($pendingEdits as $pe):
$preview = $pe['field'] === 'hours'
? '(hours update)'
: ($pe['field'] === 'is_active'
? ($pe['new_value']==='1' ? 'Open/Active' : 'Closed/Inactive')
: substr($pe['new_value'], 0, 60).(strlen($pe['new_value'])>60?'…':''));
?>
<tr>
<td><a href="/business.php?slug=<?=e($pe['biz_slug'])?>" target="_blank" class="td-name"><?=e($pe['biz_name'])?></a></td>
<td><span class="badge badge-gold"><?=e($fieldLabels[$pe['field']] ?? $pe['field'])?></span></td>
<td style="font-size:.82rem"><?=e($pe['username'] ?? '')?></td>
<td style="font-size:.82rem;max-width:220px;color:var(--text-m)"><?=e($preview)?></td>
<td style="font-size:.78rem;color:var(--text-d)"><?=ago($pe['created_at'] ?? '')?></td>
<td><a href="/admin/biz_edits.php?biz_id=<?=$pe['biz_id']?>" class="btn btn-xs btn-primary">Review</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<a href="/admin/biz_edits.php" class="btn btn-outline btn-sm" style="margin-top:.75rem">View All Edit Requests</a>
</div>
<?php endif; ?>
<div class="g2" style="gap:1.5rem;margin-bottom:2rem">
<?php if($pendingEvts): ?>
<div>
<div class="admin-sec-title">⏳ PENDING EVENTS (<?=count($pendingEvts)?>)</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>EVENT</th><th>SUBMITTED BY</th><th>DATE</th><th></th></tr></thead>
<tbody>
<?php foreach($pendingEvts as $ev): ?>
<tr>
<td class="td-name"><?=e($ev['title'])?></td>
<td><?=e($ev['username']??'—')?></td>
<td><?=fdate($ev['event_date']??'')?></td>
<td><a href="/admin/events.php?edit=<?=$ev['id']?>" class="btn btn-xs btn-primary">Review</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
<?php if($openReports): ?>
<div>
<div class="admin-sec-title">🚩 OPEN REPORTS (<?=count($openReports)?>)</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>BUSINESS</th><th>TYPE</th><th>FROM</th><th></th></tr></thead>
<tbody>
<?php foreach($openReports as $r): ?>
<tr>
<td class="td-name"><?=e($r['biz'])?></td>
<td><span class="badge badge-gold"><?=e($r['type'])?></span></td>
<td><?=e($r['reporter'])?></td>
<td><a href="/admin/reports.php" class="btn btn-xs btn-outline">View</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
</div>
<?php if($recentForumTopics): ?>
<div style="margin-bottom:2rem">
<div class="admin-sec-title">FORUM ACTIVITY</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>TOPIC</th><th>CATEGORY</th><th>BY</th><th>REPLIES</th><th></th></tr></thead>
<tbody>
<?php foreach($recentForumTopics as $topic): ?>
<tr>
<td><a href="<?=e(forumTopicUrl($topic))?>" target="_blank" class="td-name"><?=e($topic['title'])?></a><div style="font-size:.75rem;color:var(--text-d)"><?=ago($topic['updated_at'])?></div></td>
<td><?=e($topic['category_name'])?></td>
<td><?=e($topic['username'])?></td>
<td><?=$topic['reply_count']?></td>
<td><a href="/admin/forum.php#topics" class="btn btn-xs btn-primary">Moderate</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
<div class="g2">
<div>
<div class="admin-sec-title">🏢 RECENT BUSINESSES</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>NAME</th><th>STATUS</th><th></th></tr></thead>
<tbody>
<?php foreach($recentBiz as $b): ?>
<tr>
<td class="td-name"><?=e($b['name'])?></td>
<td><?=$b['is_active']?'<span class="badge badge-green">Active</span>':'<span class="badge badge-gray">Inactive</span>'?></td>
<td><a href="/admin/businesses.php?edit=<?=$b['id']?>" class="btn btn-xs btn-outline">Edit</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<a href="/admin/businesses.php" class="btn btn-outline btn-sm" style="margin-top:.75rem">Manage All Businesses</a>
</div>
<div>
<div class="admin-sec-title">👥 RECENT USERS</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>USERNAME</th><th>JOINED</th><th></th></tr></thead>
<tbody>
<?php foreach($recentUsers as $u): ?>
<tr>
<td class="td-name"><?=e($u['username'])?><?=$u['is_admin']?' <span class="badge badge-gold">ADMIN</span>':''?></td>
<td><?=fdate($u['created_at']??'')?></td>
<td><a href="/admin/users.php?edit=<?=$u['id']?>" class="btn btn-xs btn-outline">Edit</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<a href="/admin/users.php" class="btn btn-outline btn-sm" style="margin-top:.75rem">Manage All Users</a>
</div>
</div>
<?php include __DIR__.'/admin_footer.php'; ?>