📄 Source: dashboard.php
<?php
require_once 'includes/config.php';
require_once 'includes/db.php';
require_once 'includes/auth.php';
require_once 'includes/functions.php';
requireLogin();
$user = getCurrentUser();
$selectedForum = $_GET['forum_id'] ?? null;
$statusFilter = $_GET['status'] ?? 'all';
$searchQuery = $_GET['search'] ?? '';
$forum = null;
// Get all forums the user can manage
$manageableForums = getForumsByUser($user['id']);
if ($selectedForum) {
$forum = getForum($selectedForum);
if (!$forum || !canManageForum($selectedForum, $user['id'])) {
$selectedForum = null;
$forum = null;
header('Location: dashboard.php?error=You do not have permission to manage this forum');
exit();
}
}
// Handle status update
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$forumId = $_POST['forum_id'] ?? '';
$submissionId = $_POST['submission_id'] ?? '';
$newStatus = $_POST['status'] ?? '';
$note = sanitize($_POST['note'] ?? '');
if ($forumId && $submissionId && $newStatus && canManageForum($forumId, $user['id'])) {
$updateData = [
'status' => $newStatus,
'reviewed_by' => $user['id'],
'reviewed_at' => date('Y-m-d H:i:s')
];
if ($note) {
$updateData['note'] = $note;
}
updateSubmission($forumId, $submissionId, $updateData);
header('Location: dashboard.php?forum_id=' . $forumId . '&status=' . $statusFilter . '&search=' . urlencode($searchQuery) . '&success=updated');
exit();
}
}
// Handle bulk action
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['bulk_action'])) {
$forumId = $_POST['forum_id'] ?? '';
$submissionIds = $_POST['submission_ids'] ?? [];
$bulkStatus = $_POST['bulk_status'] ?? '';
if ($forumId && !empty($submissionIds) && $bulkStatus && canManageForum($forumId, $user['id'])) {
foreach ($submissionIds as $subId) {
updateSubmission($forumId, $subId, [
'status' => $bulkStatus,
'reviewed_by' => $user['id'],
'reviewed_at' => date('Y-m-d H:i:s')
]);
}
header('Location: dashboard.php?forum_id=' . $forumId . '&status=' . $statusFilter . '&search=' . urlencode($searchQuery) . '&success=bulk_updated');
exit();
}
}
// Prepare submissions
$submissions = [];
if ($forum) {
$submissions = $forum['submissions'];
// Filter by status
if ($statusFilter !== 'all') {
$submissions = array_filter($submissions, function($sub) use ($statusFilter) {
return $sub['status'] === $statusFilter;
});
}
// Search filter
if (!empty($searchQuery)) {
$searchQuery = strtolower($searchQuery);
$submissions = array_filter($submissions, function($sub) use ($searchQuery) {
return strpos(strtolower($sub['username']), $searchQuery) !== false ||
strpos(strtolower($sub['id']), $searchQuery) !== false ||
(isset($sub['discord_id']) && strpos(strtolower($sub['discord_id']), $searchQuery) !== false);
});
}
// Sort by status (pending first) then by date (newest first)
usort($submissions, function($a, $b) {
$order = ['pending' => 0, 'approved' => 1, 'rejected' => 2];
if ($order[$a['status']] !== $order[$b['status']]) {
return $order[$a['status']] - $order[$b['status']];
}
return strtotime($b['submitted_at']) - strtotime($a['submitted_at']);
});
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - <?php echo SITE_NAME; ?></title>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300;400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/style.css">
<style>
.dashboard-layout {
display: grid;
grid-template-columns: 280px 1fr;
gap: 2rem;
align-items: start;
}
.sidebar {
background: var(--bg-card);
border-radius: 1rem;
padding: 1.5rem;
border: 1px solid var(--border-color);
position: sticky;
top: 1rem;
}
.sidebar h4 {
margin-bottom: 1rem;
font-size: 0.8rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.sidebar-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.6rem 1rem;
border-radius: 0.5rem;
margin-bottom: 0.3rem;
color: var(--text-primary);
text-decoration: none;
transition: all 0.2s;
border-left: 3px solid transparent;
cursor: pointer;
}
.sidebar-item:hover {
background: var(--option-bg);
}
.sidebar-item.active {
background: var(--option-bg);
border-left-color: var(--info);
font-weight: 600;
}
.sidebar-item .badge {
background: var(--info);
color: white;
padding: 0.1rem 0.5rem;
border-radius: 2rem;
font-size: 0.7rem;
}
.stats-bar {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.stat-box {
background: var(--bg-card);
border-radius: 0.8rem;
padding: 0.8rem;
text-align: center;
border: 1px solid var(--border-color);
}
.stat-box .number {
font-size: 1.5rem;
font-weight: 800;
}
.stat-box .label {
font-size: 0.7rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.stat-box.pending .number { color: var(--warning); }
.stat-box.approved .number { color: var(--success); }
.stat-box.rejected .number { color: var(--error); }
.stat-box.total .number { color: var(--info); }
.filter-bar {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
align-items: center;
}
.filter-btn {
padding: 0.3rem 1rem;
border-radius: 2rem;
border: 2px solid var(--border-color);
background: transparent;
color: var(--text-primary);
cursor: pointer;
transition: all 0.2s;
text-decoration: none;
font-size: 0.85rem;
}
.filter-btn:hover {
background: var(--option-bg);
}
.filter-btn.active {
background: var(--info);
color: white;
border-color: var(--info);
}
.search-box {
flex: 1;
min-width: 200px;
padding: 0.4rem 1rem;
border-radius: 2rem;
border: 2px solid var(--border-color);
background: var(--input-bg);
color: var(--input-text);
font-size: 0.85rem;
}
.search-box:focus {
outline: none;
border-color: var(--input-focus);
}
.submission-card {
background: var(--bg-card);
border-radius: 0.8rem;
padding: 0.8rem 1rem;
margin-bottom: 0.5rem;
border: 1px solid var(--border-color);
transition: all 0.2s;
cursor: pointer;
}
.submission-card:hover {
border-color: var(--info);
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.submission-card .row {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
}
.submission-card .left {
display: flex;
align-items: center;
gap: 0.8rem;
flex-wrap: wrap;
min-width: 200px;
}
.submission-card .username {
font-weight: 600;
font-size: 0.95rem;
}
.submission-card .username .discord-tag {
font-size: 0.7rem;
color: var(--text-secondary);
font-weight: 400;
}
.submission-card .time {
font-size: 0.7rem;
color: var(--text-secondary);
}
.submission-card .status-badge {
padding: 0.15rem 0.6rem;
border-radius: 2rem;
font-size: 0.7rem;
font-weight: 600;
}
.status-pending { background: var(--warning); color: white; }
.status-approved { background: var(--success); color: white; }
.status-rejected { background: var(--error); color: white; }
.submission-card .preview {
font-size: 0.8rem;
color: var(--text-secondary);
margin-top: 0.3rem;
padding-left: 2.5rem;
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.submission-card .preview .answer-preview {
background: var(--code-bg);
padding: 0.1rem 0.5rem;
border-radius: 0.3rem;
font-size: 0.75rem;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.submission-card .actions {
display: flex;
gap: 0.3rem;
align-items: center;
flex-wrap: wrap;
margin-top: 0.3rem;
padding-left: 2.5rem;
}
.submission-card .actions select {
padding: 0.2rem 0.5rem;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
background: var(--input-bg);
color: var(--input-text);
font-size: 0.75rem;
}
.submission-card .actions .action-btn {
padding: 0.2rem 0.8rem;
border-radius: 0.5rem;
border: none;
cursor: pointer;
font-size: 0.75rem;
font-weight: 600;
transition: all 0.2s;
}
.action-btn.approve {
background: var(--success);
color: white;
}
.action-btn.approve:hover {
background: #059669;
}
.action-btn.reject {
background: var(--error);
color: white;
}
.action-btn.reject:hover {
background: #dc2626;
}
.action-btn.pending {
background: var(--warning);
color: white;
}
.action-btn.pending:hover {
background: #d97706;
}
.submission-details {
display: none;
margin-top: 0.5rem;
padding-top: 0.5rem;
border-top: 1px solid var(--border-color);
padding-left: 2.5rem;
}
.submission-details.show {
display: block;
}
.submission-details .answer-item {
padding: 0.3rem 0;
font-size: 0.85rem;
border-bottom: 1px solid var(--border-color);
display: flex;
gap: 0.5rem;
}
.submission-details .answer-item:last-child {
border-bottom: none;
}
.submission-details .answer-item .q {
font-weight: 600;
min-width: 150px;
color: var(--text-secondary);
}
.submission-details .answer-item .a {
color: var(--text-primary);
}
.submission-details .note-box {
margin-top: 0.5rem;
padding: 0.5rem;
background: var(--code-bg);
border-radius: 0.5rem;
font-size: 0.85rem;
}
.submission-details .note-box .label {
font-weight: 600;
color: var(--text-secondary);
}
.expand-icon {
cursor: pointer;
transition: transform 0.2s;
display: inline-block;
}
.expand-icon.rotated {
transform: rotate(180deg);
}
.bulk-bar {
background: var(--bg-card);
border-radius: 0.8rem;
padding: 0.8rem 1rem;
margin-bottom: 1rem;
border: 1px solid var(--border-color);
display: none;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.bulk-bar.show {
display: flex;
}
.bulk-bar .bulk-select {
padding: 0.3rem 0.8rem;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
background: var(--input-bg);
color: var(--input-text);
}
.bulk-bar .bulk-btn {
padding: 0.3rem 1rem;
border-radius: 0.5rem;
border: none;
cursor: pointer;
font-weight: 600;
font-size: 0.8rem;
}
.bulk-bar .bulk-btn.approve {
background: var(--success);
color: white;
}
.bulk-bar .bulk-btn.reject {
background: var(--error);
color: white;
}
.bulk-bar .bulk-btn.pending {
background: var(--warning);
color: white;
}
.bulk-bar .selected-count {
font-size: 0.8rem;
color: var(--text-secondary);
}
.checkbox-col {
width: 20px;
text-align: center;
}
.checkbox-col input[type="checkbox"] {
width: 16px;
height: 16px;
cursor: pointer;
}
.forum-info-box {
background: var(--bg-card);
border-radius: 0.8rem;
padding: 1rem 1.2rem;
margin-bottom: 1rem;
border: 1px solid var(--border-color);
}
.forum-info-box h2 {
color: var(--text-primary);
font-size: 1.3rem;
margin-bottom: 0.3rem;
}
.forum-info-box .meta {
color: var(--text-secondary);
font-size: 0.85rem;
display: flex;
flex-wrap: wrap;
gap: 0.8rem;
align-items: center;
}
.forum-info-box .meta .badge-owner {
background: var(--warning);
color: white;
padding: 0.1rem 0.5rem;
border-radius: 2rem;
font-size: 0.7rem;
}
.forum-info-box .meta .badge-admin {
background: var(--info);
color: white;
padding: 0.1rem 0.5rem;
border-radius: 2rem;
font-size: 0.7rem;
}
@media (max-width: 768px) {
.dashboard-layout {
grid-template-columns: 1fr;
}
.sidebar {
position: relative;
}
.submission-card .left {
min-width: 100px;
}
.submission-card .preview {
padding-left: 0;
flex-direction: column;
gap: 0.2rem;
}
.submission-card .actions {
padding-left: 0;
}
.submission-details {
padding-left: 0;
}
.submission-details .answer-item {
flex-direction: column;
}
.submission-details .answer-item .q {
min-width: auto;
}
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="theme-btn" data-theme="light" title="Light mode">☀️</button>
<button class="theme-btn" data-theme="dark" title="Dark mode">🌙</button>
</div>
<div class="container">
<header class="header">
<div class="header-top">
<h1>📊 Dashboard</h1>
<div class="header-actions">
<a href="index.php" class="back-link">← Back</a>
<a href="create-forum.php" class="btn-primary">➕ New Forum</a>
</div>
</div>
<p class="subhead">Review and manage applications</p>
</header>
<?php if (isset($_GET['success'])): ?>
<div class="success-message">
✅ <?php echo $_GET['success'] === 'updated' ? 'Application updated successfully!' : 'Bulk update completed!'; ?>
</div>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<div class="error-message">⚠️ <?php echo htmlspecialchars($_GET['error']); ?></div>
<?php endif; ?>
<div class="dashboard-layout">
<!-- Sidebar -->
<div class="sidebar">
<h4>📋 Your Forums</h4>
<?php if (empty($manageableForums)): ?>
<p style="color: var(--text-secondary); font-size: 0.9rem;">No forums to review</p>
<a href="create-forum.php" class="btn-primary" style="display: block; text-align: center; margin-top: 0.5rem; font-size: 0.8rem;">Create One</a>
<?php else: ?>
<?php foreach ($manageableForums as $f): ?>
<a href="dashboard.php?forum_id=<?php echo $f['id']; ?>"
class="sidebar-item <?php echo $selectedForum === $f['id'] ? 'active' : ''; ?>">
<span><?php echo htmlspecialchars(truncate($f['title'], 25)); ?></span>
<span class="badge"><?php echo count($f['submissions']); ?></span>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="content">
<?php if (!$forum): ?>
<div class="empty-state">
<div style="font-size: 3rem; margin-bottom: 1rem;">👈</div>
<h3>Select a forum from the sidebar</h3>
<p style="color: var(--text-secondary);">Choose a forum to review its applications</p>
</div>
<?php else: ?>
<!-- ===== FORUM INFO SECTION - HERE ===== -->
<div class="forum-info-box">
<h2>📋 <?php echo htmlspecialchars($forum['title']); ?></h2>
<div class="meta">
<span>📝 <?php echo count($forum['submissions']); ?> total submissions</span>
<span>❓ <?php echo count($forum['questions']); ?> questions</span>
<span>⏱️ <?php echo $forum['time_limit']; ?>min limit</span>
<?php if (isForumOwner($forum['id'], $user['id'])): ?>
<span class="badge-owner">👑 Owner</span>
<?php else: ?>
<span class="badge-admin">👔 Admin</span>
<?php endif; ?>
<?php if (!empty($forum['description'])): ?>
<span style="color: var(--text-secondary); font-size: 0.8rem;">📄 <?php echo htmlspecialchars($forum['description']); ?></span>
<?php endif; ?>
</div>
</div>
<!-- Share Forum -->
<div style="background: var(--bg-card); border-radius: 0.8rem; padding: 0.8rem 1rem; margin-bottom: 1rem; border: 1px solid var(--border-color); display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;">
<span style="font-weight: 600; font-size: 0.9rem; color: var(--text-primary);">🔗 Share Forum:</span>
<input type="text" id="shareLink" value="<?php echo BASE_URL . 'apply.php?id=' . $selectedForum; ?>" readonly style="flex: 1; min-width: 200px; padding: 0.5rem; border-radius: 0.5rem; border: 1px solid var(--border-color); background: var(--input-bg); color: var(--input-text); font-size: 0.85rem;">
<button onclick="copyToClipboard(document.getElementById('shareLink').value)" class="btn-primary" style="padding: 0.4rem 1.2rem; font-size: 0.85rem;">📋 Copy</button>
</div>
<!-- Admin Management (Owner Only) -->
<?php if (isForumOwner($selectedForum, $user['id'])): ?>
<div style="background: var(--bg-card); border-radius: 0.8rem; padding: 0.8rem 1rem; margin-bottom: 1rem; border: 1px solid var(--border-color);">
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
<span style="font-weight: 600; font-size: 0.9rem; color: var(--text-primary);">👔 Forum Admins</span>
<form method="POST" action="manage-admins.php" style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
<input type="hidden" name="forum_id" value="<?php echo $selectedForum; ?>">
<input type="hidden" name="action" value="add_admin">
<input type="text" name="username" placeholder="Add admin by username..." style="padding: 0.3rem 0.8rem; border-radius: 0.5rem; border: 1px solid var(--border-color); background: var(--input-bg); color: var(--input-text); font-size: 0.85rem;">
<button type="submit" class="btn-primary" style="padding: 0.3rem 1rem; font-size: 0.8rem;">Add</button>
</form>
</div>
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.5rem;">
<?php
$forumAdmins = $forum['admins'] ?? [];
foreach ($forumAdmins as $adminId):
$admin = getUser($adminId);
if ($admin):
?>
<div style="background: var(--code-bg); padding: 0.2rem 0.8rem; border-radius: 2rem; font-size: 0.8rem; display: flex; align-items: center; gap: 0.3rem;">
<?php echo htmlspecialchars($admin['username']); ?>
<?php if ($adminId === $forum['created_by']): ?>
<span style="color: var(--warning);">👑</span>
<?php else: ?>
<a href="manage-admins.php?forum_id=<?php echo $selectedForum; ?>&action=remove&user_id=<?php echo $adminId; ?>"
onclick="return confirm('Remove this admin?')"
style="color: var(--error); text-decoration: none; font-size: 0.7rem;">✖</a>
<?php endif; ?>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
<?php endif; ?>
<!-- Stats -->
<?php
$total = count($forum['submissions']);
$pending = count(array_filter($forum['submissions'], function($s) { return $s['status'] === 'pending'; }));
$approved = count(array_filter($forum['submissions'], function($s) { return $s['status'] === 'approved'; }));
$rejected = count(array_filter($forum['submissions'], function($s) { return $s['status'] === 'rejected'; }));
?>
<div class="stats-bar">
<div class="stat-box total"><div class="number"><?php echo $total; ?></div><div class="label">Total</div></div>
<div class="stat-box pending"><div class="number"><?php echo $pending; ?></div><div class="label">⏳ Pending</div></div>
<div class="stat-box approved"><div class="number"><?php echo $approved; ?></div><div class="label">✅ Approved</div></div>
<div class="stat-box rejected"><div class="number"><?php echo $rejected; ?></div><div class="label">❌ Rejected</div></div>
</div>
<!-- Filters -->
<div class="filter-bar">
<a href="?forum_id=<?php echo $selectedForum; ?>&status=all" class="filter-btn <?php echo $statusFilter === 'all' ? 'active' : ''; ?>">All</a>
<a href="?forum_id=<?php echo $selectedForum; ?>&status=pending" class="filter-btn <?php echo $statusFilter === 'pending' ? 'active' : ''; ?>">⏳ Pending</a>
<a href="?forum_id=<?php echo $selectedForum; ?>&status=approved" class="filter-btn <?php echo $statusFilter === 'approved' ? 'active' : ''; ?>">✅ Approved</a>
<a href="?forum_id=<?php echo $selectedForum; ?>&status=rejected" class="filter-btn <?php echo $statusFilter === 'rejected' ? 'active' : ''; ?>">❌ Rejected</a>
<form method="GET" style="flex: 1; min-width: 200px; display: flex; gap: 0.5rem;">
<input type="hidden" name="forum_id" value="<?php echo $selectedForum; ?>">
<input type="hidden" name="status" value="<?php echo $statusFilter; ?>">
<input type="text" name="search" class="search-box" placeholder="🔍 Search by username or ID..." value="<?php echo htmlspecialchars($searchQuery); ?>">
<button type="submit" class="btn-secondary" style="padding: 0.3rem 1rem;">Search</button>
</form>
</div>
<!-- Bulk Actions -->
<form method="POST" action="" id="bulkForm">
<input type="hidden" name="forum_id" value="<?php echo $selectedForum; ?>">
<input type="hidden" name="bulk_action" value="1">
<div class="bulk-bar" id="bulkBar">
<span class="selected-count" id="selectedCount">0 selected</span>
<select name="bulk_status" class="bulk-select">
<option value="">Change status...</option>
<option value="pending">⏳ Pending</option>
<option value="approved">✅ Approve</option>
<option value="rejected">❌ Reject</option>
</select>
<button type="submit" class="bulk-btn approve" onclick="return confirm('Apply to all selected?')">Apply</button>
<button type="button" class="bulk-btn" style="background: var(--error); color: white;" onclick="deselectAll()">Clear</button>
</div>
<?php if (empty($submissions)): ?>
<div class="empty-state">
<p>📭 No submissions match your filters</p>
</div>
<?php else: ?>
<?php foreach ($submissions as $sub): ?>
<?php
$answers = $sub['answers'] ?? [];
$firstAnswers = array_slice($answers, 0, 2);
$hasMore = count($answers) > 2;
?>
<div class="submission-card" id="sub-<?php echo $sub['id']; ?>">
<div class="row">
<div class="left">
<div class="checkbox-col">
<input type="checkbox" name="submission_ids[]" value="<?php echo $sub['id']; ?>" onchange="updateBulkBar()">
</div>
<span class="username">
<?php echo htmlspecialchars($sub['username']); ?>
<?php if (isset($sub['discord_id'])): ?>
<span class="discord-tag">🟣 #<?php echo htmlspecialchars(substr($sub['discord_id'], -4)); ?></span>
<?php endif; ?>
</span>
<span class="status-badge status-<?php echo $sub['status']; ?>">
<?php echo $sub['status'] === 'pending' ? '⏳' : ($sub['status'] === 'approved' ? '✅' : '❌'); ?>
<?php echo ucfirst($sub['status']); ?>
</span>
<span class="time">📅 <?php echo timeAgo($sub['submitted_at']); ?></span>
<?php if (!empty($sub['note'])): ?>
<span style="font-size: 0.7rem; color: var(--info);">📝</span>
<?php endif; ?>
</div>
<span class="expand-icon" onclick="toggleDetails('<?php echo $sub['id']; ?>')">▼</span>
</div>
<!-- Preview answers -->
<div class="preview">
<?php foreach ($firstAnswers as $ans): ?>
<span class="answer-preview">
<?php echo htmlspecialchars(truncate($ans['answer'] ?? '(no answer)', 30)); ?>
</span>
<?php endforeach; ?>
<?php if ($hasMore): ?>
<span class="answer-preview" style="color: var(--text-secondary);">+<?php echo count($answers) - 2; ?> more</span>
<?php endif; ?>
</div>
<!-- Quick actions -->
<div class="actions">
<form method="POST" action="" style="display: inline;">
<input type="hidden" name="forum_id" value="<?php echo $selectedForum; ?>">
<input type="hidden" name="submission_id" value="<?php echo $sub['id']; ?>">
<input type="hidden" name="action" value="update">
<?php if ($sub['status'] !== 'approved'): ?>
<button type="submit" name="status" value="approved" class="action-btn approve">✅ Approve</button>
<?php endif; ?>
<?php if ($sub['status'] !== 'rejected'): ?>
<button type="submit" name="status" value="rejected" class="action-btn reject">❌ Reject</button>
<?php endif; ?>
<?php if ($sub['status'] !== 'pending'): ?>
<button type="submit" name="status" value="pending" class="action-btn pending">⏳ Pending</button>
<?php endif; ?>
</form>
</div>
<!-- Expanded details -->
<div class="submission-details" id="details-<?php echo $sub['id']; ?>">
<?php foreach ($answers as $ans): ?>
<div class="answer-item">
<span class="q"><?php echo htmlspecialchars($ans['question']); ?></span>
<span class="a">➜ <?php echo htmlspecialchars($ans['answer'] ?? '(No answer)'); ?></span>
</div>
<?php endforeach; ?>
<?php if (!empty($sub['note'])): ?>
<div class="note-box">
<span class="label">📝 Staff Note:</span>
<?php echo htmlspecialchars($sub['note']); ?>
</div>
<?php endif; ?>
<!-- Add note form -->
<form method="POST" action="" style="margin-top: 0.5rem;">
<input type="hidden" name="forum_id" value="<?php echo $selectedForum; ?>">
<input type="hidden" name="submission_id" value="<?php echo $sub['id']; ?>">
<input type="hidden" name="action" value="update">
<input type="hidden" name="status" value="<?php echo $sub['status']; ?>">
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
<input type="text" name="note" placeholder="Add a note..." style="flex: 1; min-width: 150px; padding: 0.3rem 0.8rem; border-radius: 0.5rem; border: 1px solid var(--border-color); background: var(--input-bg); color: var(--input-text);">
<button type="submit" class="btn-secondary" style="padding: 0.3rem 1rem; font-size: 0.8rem;">Add Note</button>
</div>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</form>
<?php endif; ?>
</div>
</div>
<footer class="footer">
<p>📊 Dashboard v2.0 | Click ▼ to expand answers | Bulk actions available</p>
</footer>
</div>
<script src="assets/script.js"></script>
<script>
function toggleDetails(id) {
const details = document.getElementById('details-' + id);
const icon = document.querySelector(`#sub-${id} .expand-icon`);
if (details) {
details.classList.toggle('show');
if (icon) {
icon.classList.toggle('rotated');
}
}
}
function updateBulkBar() {
const checkboxes = document.querySelectorAll('input[name="submission_ids[]"]:checked');
const count = checkboxes.length;
const bar = document.getElementById('bulkBar');
const countDisplay = document.getElementById('selectedCount');
if (count > 0) {
bar.classList.add('show');
countDisplay.textContent = count + ' selected';
} else {
bar.classList.remove('show');
}
}
function deselectAll() {
document.querySelectorAll('input[name="submission_ids[]"]').forEach(cb => cb.checked = false);
updateBulkBar();
}
// Select all on shift-click
let lastChecked = null;
document.addEventListener('click', function(e) {
if (e.target.matches('input[name="submission_ids[]"]')) {
if (e.shiftKey && lastChecked !== null) {
const checkboxes = document.querySelectorAll('input[name="submission_ids[]"]');
let start = Array.from(checkboxes).indexOf(lastChecked);
let end = Array.from(checkboxes).indexOf(e.target);
if (start > end) [start, end] = [end, start];
for (let i = start; i <= end; i++) {
checkboxes[i].checked = lastChecked.checked;
}
updateBulkBar();
}
lastChecked = e.target;
}
});
</script>
</body>
</html>
← Back