leaderboard

This commit is contained in:
aldo 2025-12-15 22:59:56 +07:00
parent d27b2bf3f9
commit 8ae4f0989a

View File

@ -1,67 +1,257 @@
<?php
require_once 'db.php';
// Auto-create table if it doesn't exist
try {
$checkTable = $conn->query("SHOW TABLES LIKE 'leaderboard_sudoku'");
if ($checkTable->rowCount() == 0) {
$createSql = "
CREATE TABLE leaderboard_sudoku (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
difficulty VARCHAR(10),
time_seconds INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
$conn->exec($createSql);
}
} catch (PDOException $e) {
// Fail silently or log, but attempting to continue might show empty leaderboard instead of crash
}
// Helper function to get top 10 by difficulty
function getLeaderboard($conn, $difficulty) {
$sql = "
SELECT username, difficulty, time_seconds
SELECT username, time_seconds, created_at
FROM leaderboard_sudoku
ORDER BY difficulty, time_seconds ASC
WHERE difficulty = :difficulty
ORDER BY time_seconds ASC
LIMIT 10
";
$stmt = $conn->prepare($sql);
$stmt->execute(['difficulty' => $difficulty]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
$stmt = $conn->query($sql);
$data = $stmt->fetchAll();
// Fetch data for each level
$easyData = getLeaderboard($conn, 'easy');
$mediumData = getLeaderboard($conn, 'medium');
$hardData = getLeaderboard($conn, 'hard');
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaderboard Sudoku</title>
<style>
.leaderboard {
background: #1e1e1e;
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #121212;
color: white;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
border-radius: 10px;
width: 350px;
}
.leaderboard table {
h2 { margin-bottom: 20px; }
.leaderboard-container {
width: 100%;
max-width: 500px;
background: #1e1e1e;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 15px rgba(0,0,0,0.5);
}
/* Tabs Navigation */
.tabs {
display: flex;
width: 100%;
}
.tab-btn {
flex: 1;
padding: 15px;
border: none;
cursor: pointer;
font-size: 16px;
font-weight: bold;
color: #ccc;
background-color: #2c2c2c;
transition: 0.3s;
border-bottom: 4px solid transparent;
}
.tab-btn:hover {
background-color: #333;
color: white;
}
/* Active Tab Styling - Colors requested: Easy=Green, Medium=Yellow, Hard=Blue */
.tab-btn.active.easy {
background-color: #1e1e1e;
color: #4CAF50; /* Green */
border-bottom-color: #4CAF50;
}
.tab-btn.active.medium {
background-color: #1e1e1e;
color: #2196F3; /* Blue */
border-bottom-color: #2196F3;
}
.tab-btn.active.hard {
background-color: #1e1e1e;
color: #f44336; /* Red */
border-bottom-color: #f44336;
}
/* Content Sections */
.tab-content {
display: none; /* Hidden by default */
padding: 20px;
animation: fadeIn 0.4s;
}
.tab-content.active {
display: block;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
}
.leaderboard th, .leaderboard td {
padding: 8px;
border-bottom: 1px solid #444;
text-align: center;
th, td {
text-align: left;
padding: 12px;
border-bottom: 1px solid #333;
}
.leaderboard th {
background: #333;
th {
color: #888;
font-size: 14px;
text-transform: uppercase;
}
tr:last-child td {
border-bottom: none;
}
/* Rank Colors */
.rank-1 { color: gold; font-weight: bold; }
.rank-2 { color: silver; font-weight: bold; }
.rank-3 { color: #cd7f32; font-weight: bold; } /* Bronze */
.back-btn {
margin-top: 20px;
padding: 10px 20px;
background-color: #333;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
text-decoration: none;
font-weight: bold;
transition: 0.2s;
}
.back-btn:hover {
background-color: #444;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(5px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div class="leaderboard">
<h3>🏆 Leaderboard</h3>
<h2>🏆 Leaderboard</h2>
<table>
<tr>
<th>User</th>
<th>Level</th>
<th>Time</th>
</tr>
<?php if (count($data) > 0): ?>
<?php foreach ($data as $row): ?>
<tr>
<td><?= htmlspecialchars($row['username']) ?></td>
<td><?= strtoupper($row['difficulty']) ?></td>
<td>
<?= sprintf(
"%02d:%02d",
floor($row['time_seconds'] / 60),
$row['time_seconds'] % 60
) ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="3">Belum ada data</td>
</tr>
<?php endif; ?>
</table>
<div class="leaderboard-container">
<!-- Tabs -->
<div class="tabs">
<button class="tab-btn easy active" onclick="openTab('easy')">MUDAH</button>
<button class="tab-btn medium" onclick="openTab('medium')">SEDANG</button>
<button class="tab-btn hard" onclick="openTab('hard')">SULIT</button>
</div>
<!-- Easy Section -->
<div id="easy" class="tab-content active">
<h3 style="color: #4CAF50; margin-top: 0;">Level Mudah</h3>
<?php renderTable($easyData); ?>
</div>
<!-- Medium Section -->
<div id="medium" class="tab-content">
<h3 style="color: #2196F3; margin-top: 0;">Level Sedang</h3>
<?php renderTable($mediumData); ?>
</div>
<!-- Hard Section -->
<div id="hard" class="tab-content">
<h3 style="color: #f44336; margin-top: 0;">Level Sulit</h3>
<?php renderTable($hardData); ?>
</div>
</div>
<a href="Sudoku.php" class="back-btn">Kembali ke Game</a>
<script>
function openTab(difficulty) {
// Hide all tab contents
const contents = document.querySelectorAll('.tab-content');
contents.forEach(content => content.classList.remove('active'));
// Deactivate all buttons
const buttons = document.querySelectorAll('.tab-btn');
buttons.forEach(btn => btn.classList.remove('active'));
// Activate specific tab and button
document.getElementById(difficulty).classList.add('active');
// Find the button that calls this function (or match by class) needs logic if I don't pass 'this'
// Using querySelector to find the button with specific class for simplicity in this context
document.querySelector(`.tab-btn.${difficulty}`).classList.add('active');
}
</script>
</body>
</html>
<?php
// Helper to render table
function renderTable($data) {
if (count($data) === 0) {
echo "<p style='color: gray; text-align: center; padding: 20px;'>Belum ada data.</p>";
return;
}
echo "<table>";
echo "<tr><th>Rank</th><th>Player</th><th>Waktu</th></tr>";
$rank = 1;
foreach ($data as $row) {
$timeStr = sprintf("%02d:%02d", floor($row['time_seconds'] / 60), $row['time_seconds'] % 60);
$rankClass = '';
if ($rank == 1) $rankClass = 'rank-1';
elseif ($rank == 2) $rankClass = 'rank-2';
elseif ($rank == 3) $rankClass = 'rank-3';
echo "<tr>";
echo "<td class='{$rankClass}'>#{$rank}</td>";
echo "<td>" . htmlspecialchars($row['username']) . "</td>";
echo "<td>{$timeStr}</td>";
echo "</tr>";
$rank++;
}
echo "</table>";
}
?>