Lokal Leaderboard
This commit is contained in:
@@ -353,7 +353,7 @@ body {
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: clamp(3rem, 1.8vw, 1.2rem);
|
||||
font-size: clamp(1.5rem, 3vw, 3rem);
|
||||
margin: clamp(8px, 1vh, 12px) 0;
|
||||
padding: clamp(6px, 1vh, 10px) clamp(12px, 2vw, 18px);
|
||||
border-radius: 20px;
|
||||
@@ -455,6 +455,61 @@ body {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* Leaderboard Styles */
|
||||
#leaderboard-container {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leaderboard-entry {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: clamp(8px, 1vh, 12px) 0;
|
||||
font-size: clamp(1.1rem, 2.2vw, 1.4rem);
|
||||
font-weight: 600;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
padding: clamp(8px, 1.5vh, 12px) clamp(12px, 2vw, 16px);
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.leaderboard-entry:hover {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.leaderboard-entry .rank {
|
||||
color: #ffd700;
|
||||
font-weight: bold;
|
||||
min-width: 30px;
|
||||
font-size: clamp(1.2rem, 2.4vw, 1.5rem);
|
||||
}
|
||||
|
||||
.leaderboard-entry .name {
|
||||
flex: 1;
|
||||
margin: 0 15px;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.leaderboard-entry .time {
|
||||
color: #00ff88;
|
||||
font-weight: bold;
|
||||
font-family: 'Courier New', monospace;
|
||||
min-width: 80px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.no-times {
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-style: italic;
|
||||
font-size: clamp(0.9rem, 1.8vw, 1.1rem);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.learning-mode {
|
||||
background: rgba(245, 157, 15, 0.2);
|
||||
border: 2px solid #f59d0f;
|
||||
|
||||
107
data/index.html
107
data/index.html
@@ -72,14 +72,33 @@
|
||||
</div>
|
||||
|
||||
<div class="best-times">
|
||||
<h3>🏆 Deine Bestzeiten heute</h3>
|
||||
<div class="best-time-row">
|
||||
<span>Bahn 1:</span>
|
||||
<span id="best1">--.-</span>
|
||||
</div>
|
||||
<div class="best-time-row">
|
||||
<span>Bahn 2:</span>
|
||||
<span id="best2">--.-</span>
|
||||
<h3>🏆 Lokales Leaderboard</h3>
|
||||
<div id="leaderboard-container">
|
||||
<div class="leaderboard-entry">
|
||||
<span class="rank">1.</span>
|
||||
<span class="name">Max Mustermann</span>
|
||||
<span class="time">23.45</span>
|
||||
</div>
|
||||
<div class="leaderboard-entry">
|
||||
<span class="rank">2.</span>
|
||||
<span class="name">Anna Schmidt</span>
|
||||
<span class="time">24.67</span>
|
||||
</div>
|
||||
<div class="leaderboard-entry">
|
||||
<span class="rank">3.</span>
|
||||
<span class="name">Tom Weber</span>
|
||||
<span class="time">25.89</span>
|
||||
</div>
|
||||
<div class="leaderboard-entry">
|
||||
<span class="rank">4.</span>
|
||||
<span class="name">Lisa Müller</span>
|
||||
<span class="time">26.12</span>
|
||||
</div>
|
||||
<div class="leaderboard-entry">
|
||||
<span class="rank">5.</span>
|
||||
<span class="name">Paul Fischer</span>
|
||||
<span class="time">27.34</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -96,6 +115,7 @@
|
||||
let learningButton = "";
|
||||
let name1 = "";
|
||||
let name2 = "";
|
||||
let leaderboardData = [];
|
||||
|
||||
// Lane Configuration
|
||||
let laneConfigType = 0; // 0=Identical, 1=Different
|
||||
@@ -336,7 +356,67 @@
|
||||
|
||||
function formatTime(seconds) {
|
||||
if (seconds === 0) return "00.00";
|
||||
return seconds.toFixed(2);
|
||||
|
||||
const totalSeconds = Math.floor(seconds);
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const remainingSeconds = totalSeconds % 60;
|
||||
const milliseconds = Math.floor((seconds - totalSeconds) * 100);
|
||||
|
||||
// Zeige Minuten nur wenn über 60 Sekunden
|
||||
if (totalSeconds >= 60) {
|
||||
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds
|
||||
.toString()
|
||||
.padStart(2, "0")}.${milliseconds.toString().padStart(2, "0")}`;
|
||||
} else {
|
||||
return `${remainingSeconds.toString().padStart(2, "0")}.${milliseconds
|
||||
.toString()
|
||||
.padStart(2, "0")}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Leaderboard Funktionen
|
||||
async function loadLeaderboard() {
|
||||
try {
|
||||
const response = await fetch("/api/leaderboard");
|
||||
const data = await response.json();
|
||||
leaderboardData = data.leaderboard || [];
|
||||
updateLeaderboardDisplay();
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Laden des Leaderboards:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLeaderboardDisplay() {
|
||||
const container = document.getElementById("leaderboard-container");
|
||||
container.innerHTML = "";
|
||||
|
||||
if (leaderboardData.length === 0) {
|
||||
container.innerHTML =
|
||||
'<div class="no-times">Noch keine Zeiten erfasst</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
leaderboardData.forEach((entry, index) => {
|
||||
const entryDiv = document.createElement("div");
|
||||
entryDiv.className = "leaderboard-entry";
|
||||
|
||||
const rankSpan = document.createElement("span");
|
||||
rankSpan.className = "rank";
|
||||
rankSpan.textContent = entry.rank + ".";
|
||||
|
||||
const nameSpan = document.createElement("span");
|
||||
nameSpan.className = "name";
|
||||
nameSpan.textContent = entry.name;
|
||||
|
||||
const timeSpan = document.createElement("span");
|
||||
timeSpan.className = "time";
|
||||
timeSpan.textContent = entry.timeFormatted;
|
||||
|
||||
entryDiv.appendChild(rankSpan);
|
||||
entryDiv.appendChild(nameSpan);
|
||||
entryDiv.appendChild(timeSpan);
|
||||
container.appendChild(entryDiv);
|
||||
});
|
||||
}
|
||||
|
||||
function updateDisplay() {
|
||||
@@ -411,10 +491,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("best1").textContent =
|
||||
best1 > 0 ? formatTime(best1) + "s" : "--.-";
|
||||
document.getElementById("best2").textContent =
|
||||
best2 > 0 ? formatTime(best2) + "s" : "--.-";
|
||||
// Leaderboard wird separat geladen
|
||||
|
||||
// Namen anzeigen/verstecken
|
||||
const name1Element = document.getElementById("name1");
|
||||
@@ -528,6 +605,10 @@
|
||||
// Initial load
|
||||
syncFromBackend();
|
||||
loadLaneConfig();
|
||||
loadLeaderboard();
|
||||
|
||||
// Leaderboard alle 5 Sekunden aktualisieren
|
||||
setInterval(loadLeaderboard, 5000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user