| Server IP : 173.209.174.21 / Your IP : 216.73.216.89 Web Server : Apache/2.4.58 (Ubuntu) System : Linux wcfs-server 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 User : nodor ( 1000) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/thelittlebigshow/app/admin/ |
Upload File : |
<?php
session_start();
ob_start();
require_once 'config/config.php';
require_once BASE_PATH . '/includes/auth_validate.php';
include_once("../db.php");
include_once("../voting_helpers.php");
ensureVotingSettingColumns($conn);
function ensureDashboardVoteScoreColumns($conn)
{
$columns = [];
$result = mysqli_query($conn, "SHOW COLUMNS FROM `vote`");
if (!$result) {
return false;
}
while ($row = mysqli_fetch_assoc($result)) {
$columns[$row['Field']] = true;
}
$neededColumns = [
'total_score' => "SMALLINT UNSIGNED DEFAULT NULL",
];
foreach ($neededColumns as $column => $definition) {
if (!isset($columns[$column])) {
if (!mysqli_query($conn, "ALTER TABLE `vote` ADD COLUMN `$column` $definition")) {
return false;
}
}
}
return true;
}
ensureDashboardVoteScoreColumns($conn);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_voting_settings'])) {
$votingOpen = isset($_POST['voting_open']) ? 1 : 0;
$allowUnscoredAfterClose = isset($_POST['allow_unscored_after_close']) ? 1 : 0;
$closedOverridePassword = trim($_POST['closed_override_password'] ?? '');
$closeAtRaw = trim($_POST['voting_close_at'] ?? '');
$closeAt = null;
if ($closeAtRaw !== '') {
$parsedCloseAt = strtotime($closeAtRaw);
if ($parsedCloseAt !== false) {
$closeAt = date('Y-m-d H:i:s', $parsedCloseAt);
}
}
$updateStmt = mysqli_prepare($conn, "UPDATE settings SET voting_open = ?, voting_close_at = ?, allow_unscored_after_close = ?, closed_override_password = ? WHERE id = 1");
mysqli_stmt_bind_param($updateStmt, "isis", $votingOpen, $closeAt, $allowUnscoredAfterClose, $closedOverridePassword);
if (mysqli_stmt_execute($updateStmt)) {
$_SESSION['success'] = "Voting settings updated.";
} else {
$_SESSION['failure'] = "Voting settings could not be updated.";
}
header("Location: voting_dashboard.php");
exit;
}
$settings = getVotingSettings($conn);
$votingClosed = isVotingClosed($settings);
$closeTimestamp = !empty($settings['voting_close_at']) ? strtotime($settings['voting_close_at']) : null;
$currentYear = date('Y');
$summary = [
'total_vehicles' => 0,
'scored_vehicles' => 0,
'unscored_vehicles' => 0,
'people_choice_votes' => 0,
];
$summarySql = "
SELECT
COUNT(*) AS total_vehicles,
SUM(CASE WHEN score_counts.score_count > 0 THEN 1 ELSE 0 END) AS scored_vehicles,
SUM(CASE WHEN score_counts.score_count IS NULL OR score_counts.score_count = 0 THEN 1 ELSE 0 END) AS unscored_vehicles,
COALESCE(SUM(vehicles.fav_vote), 0) AS people_choice_votes
FROM vehicles
LEFT JOIN (
SELECT vehicle_id, COUNT(*) AS score_count
FROM vote
GROUP BY vehicle_id
) score_counts ON score_counts.vehicle_id = vehicles.id
WHERE YEAR(vehicles.created_date) = ?
AND vehicles.status = 1
";
if ($summaryStmt = mysqli_prepare($conn, $summarySql)) {
mysqli_stmt_bind_param($summaryStmt, "i", $currentYear);
mysqli_stmt_execute($summaryStmt);
$summaryResult = mysqli_stmt_get_result($summaryStmt);
$summaryRow = mysqli_fetch_assoc($summaryResult);
if ($summaryRow) {
$summary = array_merge($summary, $summaryRow);
}
}
$categoryResults = [];
$categorySql = "
SELECT
vehicles.id,
vehicles.name,
vehicles.vehicle_maker,
vehicles.vehicle_model,
vehicles.vehicle_year,
vehicles.category,
COUNT(vote.id) AS score_count,
COALESCE(SUM(vote.total_score), 0) AS total_score,
COALESCE(ROUND(AVG(vote.total_score), 1), 0) AS average_score
FROM vehicles
LEFT JOIN vote ON vote.vehicle_id = vehicles.id
WHERE YEAR(vehicles.created_date) = ?
AND vehicles.status = 1
GROUP BY vehicles.id, vehicles.name, vehicles.vehicle_maker, vehicles.vehicle_model, vehicles.vehicle_year, vehicles.category
ORDER BY vehicles.category ASC, total_score DESC, average_score DESC, score_count DESC, vehicles.id ASC
";
if ($categoryStmt = mysqli_prepare($conn, $categorySql)) {
mysqli_stmt_bind_param($categoryStmt, "i", $currentYear);
mysqli_stmt_execute($categoryStmt);
$categoryResult = mysqli_stmt_get_result($categoryStmt);
while ($row = mysqli_fetch_assoc($categoryResult)) {
$category = $row['category'] ?: 'Uncategorized';
if (!isset($categoryResults[$category])) {
$categoryResults[$category] = [];
}
if ((int) $row['score_count'] > 0 && count($categoryResults[$category]) < 3) {
$categoryResults[$category][] = $row;
}
}
}
$peopleChoiceRows = [];
$peopleChoiceSql = "
SELECT id, name, vehicle_maker, vehicle_model, vehicle_year, category, fav_vote
FROM vehicles
WHERE YEAR(created_date) = ?
AND status = 1
ORDER BY CAST(fav_vote AS UNSIGNED) DESC, id ASC
LIMIT 10
";
if ($peopleStmt = mysqli_prepare($conn, $peopleChoiceSql)) {
mysqli_stmt_bind_param($peopleStmt, "i", $currentYear);
mysqli_stmt_execute($peopleStmt);
$peopleResult = mysqli_stmt_get_result($peopleStmt);
while ($row = mysqli_fetch_assoc($peopleResult)) {
$peopleChoiceRows[] = $row;
}
}
$unscoredByCategory = [];
$unscoredSql = "
SELECT vehicles.category, COUNT(*) AS unscored_count
FROM vehicles
LEFT JOIN vote ON vote.vehicle_id = vehicles.id
WHERE YEAR(vehicles.created_date) = ?
AND vehicles.status = 1
GROUP BY vehicles.id, vehicles.category
HAVING COUNT(vote.id) = 0
";
if ($unscoredStmt = mysqli_prepare($conn, $unscoredSql)) {
mysqli_stmt_bind_param($unscoredStmt, "i", $currentYear);
mysqli_stmt_execute($unscoredStmt);
$unscoredResult = mysqli_stmt_get_result($unscoredStmt);
while ($row = mysqli_fetch_assoc($unscoredResult)) {
$category = $row['category'] ?: 'Uncategorized';
if (!isset($unscoredByCategory[$category])) {
$unscoredByCategory[$category] = 0;
}
$unscoredByCategory[$category]++;
}
}
include BASE_PATH . '/includes/header.php';
?>
<style>
.dashboard-card {
border: 1px solid #ddd;
border-radius: 6px;
margin-bottom: 18px;
padding: 16px;
}
.metric {
font-size: 30px;
font-weight: 700;
}
.status-open {
color: #2e7d32;
font-weight: 700;
}
.status-closed {
color: #b71c1c;
font-weight: 700;
}
</style>
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Voting Dashboard</h1>
</div>
</div>
<?php include BASE_PATH . '/includes/flash_messages.php'; ?>
<div class="row">
<div class="col-md-3">
<div class="dashboard-card">
<div>Total Vehicles</div>
<div class="metric"><?php echo (int) $summary['total_vehicles']; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="dashboard-card">
<div>Scored Vehicles</div>
<div class="metric"><?php echo (int) $summary['scored_vehicles']; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="dashboard-card">
<div>Not Scored</div>
<div class="metric"><?php echo (int) $summary['unscored_vehicles']; ?></div>
</div>
</div>
<div class="col-md-3">
<div class="dashboard-card">
<div>People's Choice Votes</div>
<div class="metric"><?php echo (int) $summary['people_choice_votes']; ?></div>
</div>
</div>
</div>
<div class="dashboard-card">
<h3>Voting Controls</h3>
<p>
Status:
<?php if ($votingClosed): ?>
<span class="status-closed">Closed</span>
<?php else: ?>
<span class="status-open">Open</span>
<?php endif; ?>
</p>
<p>
Countdown:
<strong id="voting-countdown">
<?php echo $closeTimestamp ? "Calculating..." : "No close time set"; ?>
</strong>
</p>
<form action="" method="POST" class="form-inline">
<label class="checkbox-inline">
<input type="checkbox" name="voting_open" value="1" <?php echo !empty($settings['voting_open']) ? 'checked' : ''; ?>>
Voting open
</label>
<label for="voting_close_at" style="margin-left: 16px;">Auto-close time</label>
<input type="datetime-local" id="voting_close_at" name="voting_close_at" class="form-control" value="<?php echo !empty($settings['voting_close_at']) ? htmlspecialchars(date('Y-m-d\TH:i', strtotime($settings['voting_close_at'])), ENT_QUOTES) : ''; ?>">
<label class="checkbox-inline" style="margin-left: 16px;">
<input type="checkbox" name="allow_unscored_after_close" value="1" <?php echo !empty($settings['allow_unscored_after_close']) ? 'checked' : ''; ?>>
Allow unscored judging after close
</label>
<label for="closed_override_password" style="margin-left: 16px;">Closed-vote password</label>
<input type="text" id="closed_override_password" name="closed_override_password" class="form-control" value="<?php echo htmlspecialchars($settings['closed_override_password'] ?? '', ENT_QUOTES); ?>">
<button type="submit" name="save_voting_settings" class="btn btn-info" style="margin-left: 12px;">Save</button>
</form>
<div style="margin-top: 14px;">
<a href="announcer_export.php" class="btn btn-success" target="_blank">Announcer Export</a>
<a href="vote_adjustments.php" class="btn btn-warning">Adjust Vote Counts</a>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="dashboard-card">
<h3>Top 3 By Category</h3>
<?php foreach ($categoryResults as $category => $rows): ?>
<h4><?php echo htmlspecialchars($category); ?></h4>
<?php if (count($rows) > 0): ?>
<table class="table table-condensed table-striped">
<thead>
<tr>
<th>Place</th>
<th>Vehicle</th>
<th>Owner</th>
<th>Cards</th>
<th>Total</th>
<th>Average</th>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $index => $row): ?>
<tr>
<td><?php echo $index + 1; ?></td>
<td><?php echo htmlspecialchars(trim($row['vehicle_year'] . ' ' . $row['vehicle_maker'] . ' ' . $row['vehicle_model'])); ?></td>
<td><?php echo htmlspecialchars($row['name']); ?></td>
<td><?php echo (int) $row['score_count']; ?></td>
<td><?php echo (int) $row['total_score']; ?></td>
<td><?php echo htmlspecialchars($row['average_score']); ?> / 80</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>No scored vehicles yet.</p>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<div class="col-md-4">
<div class="dashboard-card">
<h3>People's Choice</h3>
<table class="table table-condensed table-striped">
<thead>
<tr>
<th>Rank</th>
<th>Vehicle</th>
<th>Votes</th>
</tr>
</thead>
<tbody>
<?php foreach ($peopleChoiceRows as $index => $row): ?>
<tr>
<td><?php echo $index + 1; ?></td>
<td><?php echo htmlspecialchars(trim($row['vehicle_year'] . ' ' . $row['vehicle_maker'] . ' ' . $row['vehicle_model'])); ?></td>
<td><?php echo (int) $row['fav_vote']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="dashboard-card">
<h3>Not Scored By Category</h3>
<?php if (count($unscoredByCategory) > 0): ?>
<ul>
<?php foreach ($unscoredByCategory as $category => $count): ?>
<li><?php echo htmlspecialchars($category); ?>: <?php echo (int) $count; ?></li>
<?php endforeach; ?>
</ul>
<a href="unvoted_vehicles.php" class="btn btn-warning">Open Not Scored List</a>
<?php else: ?>
<p>All current vehicles have at least one score.</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php if ($closeTimestamp): ?>
<script>
(function () {
var closeAt = <?php echo $closeTimestamp * 1000; ?>;
var output = document.getElementById('voting-countdown');
function tick() {
var remaining = closeAt - Date.now();
if (remaining <= 0) {
output.textContent = 'Closed';
return;
}
var seconds = Math.floor(remaining / 1000);
var days = Math.floor(seconds / 86400);
seconds %= 86400;
var hours = Math.floor(seconds / 3600);
seconds %= 3600;
var minutes = Math.floor(seconds / 60);
seconds %= 60;
output.textContent = days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's';
setTimeout(tick, 1000);
}
tick();
})();
</script>
<?php endif; ?>
<?php include BASE_PATH . '/includes/footer.php'; ?>