Update
This commit is contained in:
262
public/index.html
Normal file
262
public/index.html
Normal file
@@ -0,0 +1,262 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Timer Leaderboard</title>
|
||||
<link rel="icon" type="image/x-icon" href="/pictures/favicon.ico">
|
||||
<script src="/js/page-tracking.js"></script>
|
||||
<script src="/js/cookie-utils.js"></script>
|
||||
<link rel="stylesheet" href="/css/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Notification Bubble -->
|
||||
<div class="notification-bubble" id="notificationBubble">
|
||||
<div class="notification-content">
|
||||
<div class="notification-icon">🏁</div>
|
||||
<div class="notification-text">
|
||||
<div class="notification-title" id="notificationTitle" data-de="Neue Zeit!" data-en="New Time!">New Time!</div>
|
||||
<div class="notification-subtitle" id="notificationSubtitle" data-de="Ein neuer Rekord wurde erstellt" data-en="A new record has been created">A new record has been created</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-container">
|
||||
<!-- Sticky Header Container -->
|
||||
<div class="sticky-header">
|
||||
<!-- Language Selector -->
|
||||
<div class="language-selector">
|
||||
<select id="languageSelect" onchange="changeLanguage()">
|
||||
<option value="de" data-flag="🇩🇪">Deutsch</option>
|
||||
<option value="en" data-flag="🇺🇸">English</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Admin Login Button -->
|
||||
<div class="mobile-nav-buttons">
|
||||
<a href="/login" class="admin-login-btn" id="adminLoginBtn" onclick="handleLoginClick(event)">🔐 Login</a>
|
||||
<a href="/dashboard" class="dashboard-btn" id="dashboardBtn" style="display: none;">📊 Dashboard</a>
|
||||
<button class="logout-btn" id="logoutBtn" onclick="logout()" style="display: none;">🚪 Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-section">
|
||||
<h1 class="main-title">NINJACROSS LEADERBOARD</h1>
|
||||
<p class="tagline" data-de="Die ultimative NinjaCross-Rangliste" data-en="The ultimate NinjaCross leaderboard">The ultimate NinjaCross leaderboard</p>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-grid">
|
||||
<div class="control-panel">
|
||||
<div class="control-group">
|
||||
<label class="control-label" data-de="Standort" data-en="Location">Location</label>
|
||||
<div class="location-control">
|
||||
<select class="custom-select location-select" id="locationSelect">
|
||||
<option value="">📍 Please select location</option>
|
||||
<!-- Locations are loaded dynamically -->
|
||||
</select>
|
||||
<button class="location-btn" id="findLocationBtn" onclick="findNearestLocation()" title="Find nearest location" data-de="📍 Mein Standort" data-en="📍 My Location">
|
||||
📍 My Location
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" data-de="Zeitraum" data-en="Time Period">Time Period</label>
|
||||
<div class="time-tabs">
|
||||
<button class="time-tab" data-period="today">
|
||||
<span class="tab-icon">📅</span>
|
||||
<span class="tab-text" data-de="Heute" data-en="Today">Today</span>
|
||||
</button>
|
||||
<button class="time-tab" data-period="week">
|
||||
<span class="tab-icon">📊</span>
|
||||
<span class="tab-text" data-de="Diese Woche" data-en="This Week">This Week</span>
|
||||
</button>
|
||||
<button class="time-tab" data-period="month">
|
||||
<span class="tab-icon">📈</span>
|
||||
<span class="tab-text" data-de="Dieser Monat" data-en="This Month">This Month</span>
|
||||
</button>
|
||||
<button class="time-tab active" data-period="all">
|
||||
<span class="tab-icon">♾️</span>
|
||||
<span class="tab-text" data-de="Alle Zeiten" data-en="All Times">All Times</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="refresh-btn pulse-animation" onclick="loadData()" data-de="⚡ Live Update" data-en="⚡ Live Update">
|
||||
⚡ Live Update
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="stats-panel">
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="totalPlayers">0</div>
|
||||
<div class="stat-label" data-de="Teilnehmer" data-en="Participants">Participants</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="bestTime">--:--</div>
|
||||
<div class="stat-label" data-de="Rekordzeit" data-en="Record Time">Record Time</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="totalRecords">0</div>
|
||||
<div class="stat-label" data-de="Läufe" data-en="Runs">Runs</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="leaderboard-container">
|
||||
<div class="leaderboard-header">
|
||||
<div class="active-filters" id="currentSelection">
|
||||
📍 Please select location • ♾️ All Times
|
||||
</div>
|
||||
<div class="last-sync" id="lastUpdated">
|
||||
Last Sync: Loading...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rankings-list" id="rankingList">
|
||||
<!-- Rankings will be inserted here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-links">
|
||||
<a href="/impressum.html" class="footer-link" data-de="Impressum" data-en="Imprint">Imprint</a>
|
||||
<a href="/datenschutz.html" class="footer-link" data-de="Datenschutz" data-en="Privacy">Privacy</a>
|
||||
<button id="cookie-settings-footer" class="footer-link cookie-settings-btn" data-de="Cookie-Einstellungen" data-en="Cookie Settings">Cookie Settings</button>
|
||||
</div>
|
||||
<div class="footer-text">
|
||||
<p data-de="© 2024 NinjaCross. Alle Rechte vorbehalten." data-en="© 2024 NinjaCross. All rights reserved.">© 2024 NinjaCross. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- External Libraries -->
|
||||
<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.8.1/socket.io.min.js"></script>
|
||||
|
||||
<!-- Application JavaScript -->
|
||||
<script src="/js/cookie-consent.js"></script>
|
||||
<script src="/js/index.js"></script>
|
||||
|
||||
<script>
|
||||
// iOS Detection
|
||||
function isIOS() {
|
||||
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||||
}
|
||||
|
||||
// Mobile Sticky Header Fix
|
||||
function initMobileStickyHeader() {
|
||||
const stickyHeader = document.querySelector('.sticky-header');
|
||||
if (!stickyHeader) return;
|
||||
|
||||
// Check if we're on mobile
|
||||
const isMobile = window.innerWidth <= 768;
|
||||
|
||||
if (isMobile || isIOS()) {
|
||||
// Force fixed positioning for mobile
|
||||
stickyHeader.style.position = 'fixed';
|
||||
stickyHeader.style.top = '0';
|
||||
stickyHeader.style.left = '0';
|
||||
stickyHeader.style.right = '0';
|
||||
stickyHeader.style.width = '100%';
|
||||
stickyHeader.style.zIndex = '99999';
|
||||
stickyHeader.style.marginBottom = '0';
|
||||
stickyHeader.style.borderRadius = '0';
|
||||
|
||||
// Add padding to main container
|
||||
const mainContainer = document.querySelector('.main-container');
|
||||
if (mainContainer) {
|
||||
mainContainer.style.paddingTop = '80px';
|
||||
}
|
||||
|
||||
console.log('Mobile sticky header fix applied');
|
||||
}
|
||||
}
|
||||
|
||||
// iOS Touch Event Fix
|
||||
function handleLoginClick(event) {
|
||||
console.log('Login button clicked');
|
||||
|
||||
// Prevent default behavior temporarily
|
||||
event.preventDefault();
|
||||
|
||||
// Add visual feedback
|
||||
const button = event.target;
|
||||
button.style.transform = 'scale(0.95)';
|
||||
button.style.opacity = '0.8';
|
||||
|
||||
// Reset after short delay
|
||||
setTimeout(() => {
|
||||
button.style.transform = '';
|
||||
button.style.opacity = '';
|
||||
|
||||
// Navigate to login page
|
||||
window.location.href = '/login';
|
||||
}, 150);
|
||||
}
|
||||
|
||||
// Add touch event listeners for better mobile support
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize mobile sticky header
|
||||
initMobileStickyHeader();
|
||||
|
||||
const loginBtn = document.getElementById('adminLoginBtn');
|
||||
if (loginBtn) {
|
||||
// Make sure button is clickable
|
||||
loginBtn.style.pointerEvents = 'auto';
|
||||
loginBtn.style.position = 'relative';
|
||||
loginBtn.style.zIndex = '100000';
|
||||
|
||||
// Add multiple event listeners for maximum compatibility
|
||||
loginBtn.addEventListener('touchstart', function(e) {
|
||||
console.log('Touch start on login button');
|
||||
e.preventDefault();
|
||||
this.style.transform = 'scale(0.95)';
|
||||
this.style.opacity = '0.8';
|
||||
}, { passive: false });
|
||||
|
||||
loginBtn.addEventListener('touchend', function(e) {
|
||||
console.log('Touch end on login button');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setTimeout(() => {
|
||||
this.style.transform = '';
|
||||
this.style.opacity = '';
|
||||
window.location.href = '/login';
|
||||
}, 100);
|
||||
}, { passive: false });
|
||||
|
||||
loginBtn.addEventListener('click', function(e) {
|
||||
console.log('Click on login button');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.location.href = '/login';
|
||||
});
|
||||
|
||||
// Add mousedown for desktop
|
||||
loginBtn.addEventListener('mousedown', function(e) {
|
||||
console.log('Mouse down on login button');
|
||||
this.style.transform = 'scale(0.95)';
|
||||
this.style.opacity = '0.8';
|
||||
});
|
||||
|
||||
loginBtn.addEventListener('mouseup', function(e) {
|
||||
console.log('Mouse up on login button');
|
||||
this.style.transform = '';
|
||||
this.style.opacity = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Re-apply mobile fixes on window resize
|
||||
window.addEventListener('resize', function() {
|
||||
setTimeout(initMobileStickyHeader, 100);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user