255 lines
7.0 KiB
PHP
255 lines
7.0 KiB
PHP
<?php
|
|
require_once 'db.php';
|
|
|
|
|
|
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) {
|
|
}
|
|
|
|
function getLeaderboard($conn, $difficulty) {
|
|
$allowed = ['easy', 'medium', 'hard'];
|
|
if (!in_array($difficulty, $allowed)) {
|
|
return [];
|
|
}
|
|
|
|
$sql = "
|
|
SELECT username, time_seconds, created_at
|
|
FROM leaderboard_sudoku
|
|
WHERE difficulty = :difficulty
|
|
ORDER BY time_seconds ASC
|
|
LIMIT 10
|
|
";
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->execute(['difficulty' => $difficulty]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
if (isset($_GET['api']) && isset($_GET['difficulty'])) {
|
|
header('Content-Type: application/json');
|
|
$data = getLeaderboard($conn, $_GET['difficulty']);
|
|
echo json_encode($data);
|
|
exit;
|
|
}
|
|
|
|
$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>
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
background: url("Background.jpg") no-repeat center center fixed;
|
|
background-size: cover;
|
|
color: white;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
margin: 0;
|
|
padding: 20px;
|
|
}
|
|
|
|
h2 { margin-bottom: 20px; }
|
|
|
|
.leaderboard-container {
|
|
width: 100%;
|
|
max-width: 500px;
|
|
background: white;
|
|
color: darkslategray;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
|
}
|
|
|
|
.tabs {
|
|
display: flex;
|
|
width: 100%;
|
|
}
|
|
|
|
.tab-btn {
|
|
flex: 1;
|
|
padding: 15px;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
color: dimgray;
|
|
background-color: whitesmoke;
|
|
transition: 0.3s;
|
|
border-bottom: 4px solid lightgray;
|
|
}
|
|
|
|
.tab-btn:hover {
|
|
background-color: gainsboro;
|
|
color: black;
|
|
}
|
|
|
|
.tab-btn.active.easy {
|
|
background-color: white;
|
|
color: limegreen;
|
|
border-bottom-color: limegreen;
|
|
}
|
|
.tab-btn.active.medium {
|
|
background-color: white;
|
|
color: dodgerblue;
|
|
border-bottom-color: dodgerblue;
|
|
}
|
|
.tab-btn.active.hard {
|
|
background-color: white;
|
|
color: red;
|
|
border-bottom-color: red;
|
|
}
|
|
|
|
.tab-content {
|
|
display: none;
|
|
padding: 20px;
|
|
animation: fadeIn 0.4s;
|
|
}
|
|
|
|
.tab-content.active {
|
|
display: block;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
th, td {
|
|
text-align: left;
|
|
padding: 12px;
|
|
border-bottom: 1px solid whitesmoke;
|
|
}
|
|
|
|
th {
|
|
color: gray;
|
|
font-size: 14px;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
tr:last-child td {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.rank-1 { color: gold; font-weight: bold; }
|
|
.rank-2 { color: silver; font-weight: bold; }
|
|
.rank-3 { color: chocolate; font-weight: bold; }
|
|
|
|
.back-btn {
|
|
margin-top: 20px;
|
|
padding: 10px 20px;
|
|
background-color: white;
|
|
color: darkslategray;
|
|
border: none;
|
|
border-radius: 20px;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
font-weight: bold;
|
|
transition: 0.2s;
|
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
}
|
|
.back-btn:hover {
|
|
background-color: whitesmoke;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(5px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h2>🏆 Leaderboard</h2>
|
|
|
|
<div class="leaderboard-container">
|
|
<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>
|
|
|
|
<div id="easy" class="tab-content active">
|
|
<h3 style="color: limegreen; margin-top: 0;">Level Mudah</h3>
|
|
<?php renderTable($easyData); ?>
|
|
</div>
|
|
<div id="medium" class="tab-content">
|
|
<h3 style="color: dodgerblue; margin-top: 0;">Level Sedang</h3>
|
|
<?php renderTable($mediumData); ?>
|
|
</div>
|
|
|
|
<div id="hard" class="tab-content">
|
|
<h3 style="color: red; 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) {
|
|
const contents = document.querySelectorAll('.tab-content');
|
|
contents.forEach(content => content.classList.remove('active'));
|
|
|
|
const buttons = document.querySelectorAll('.tab-btn');
|
|
buttons.forEach(btn => btn.classList.remove('active'));
|
|
|
|
document.getElementById(difficulty).classList.add('active');
|
|
document.querySelector(`.tab-btn.${difficulty}`).classList.add('active');
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
|
|
<?php
|
|
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>";
|
|
}
|
|
?>
|