This commit is contained in:
2025-05-16 01:22:20 +02:00
parent 27189d8a22
commit ee9f04bf46
11 changed files with 778 additions and 0 deletions

74
html/js/main.js Normal file
View File

@@ -0,0 +1,74 @@
document.addEventListener('DOMContentLoaded', function() {
// Mobile menu toggle
const hamburger = document.querySelector('.hamburger');
const navLinks = document.querySelector('.nav-links');
hamburger.addEventListener('click', function() {
this.classList.toggle('active');
navLinks.classList.toggle('active');
});
// Close menu when clicking a link (mobile)
document.querySelectorAll('.nav-links a').forEach(link => {
link.addEventListener('click', () => {
hamburger.classList.remove('active');
navLinks.classList.remove('active');
});
});
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const targetElement = document.querySelector(targetId);
if (targetElement) {
window.scrollTo({
top: targetElement.offsetTop - 80, // Adjusted for fixed header
behavior: 'smooth'
});
}
});
});
});
document.addEventListener('DOMContentLoaded', function() {
const serverCards = document.querySelectorAll('.server-card');
const API_URL = '/api/check-port'; // Change in production
async function checkServerStatus(card) {
const ip = card.dataset.ip;
const port = card.dataset.port;
const statusElement = card.querySelector('.status');
if (!ip || !port || !statusElement) return;
statusElement.textContent = 'Checking...';
statusElement.className = 'status unknown';
try {
const response = await fetch(`${API_URL}?host=${encodeURIComponent(ip)}&port=${port}`);
const data = await response.json();
statusElement.textContent = data.status.charAt(0).toUpperCase() + data.status.slice(1);
statusElement.className = `status ${data.status}`;
} catch (e) {
statusElement.textContent = 'Error';
statusElement.className = 'status unknown';
}
}
// Initial check
serverCards.forEach(checkServerStatus);
// Click handler for manual refresh
serverCards.forEach(card => {
card.addEventListener('click', () => checkServerStatus(card));
});
// Periodic checks every 5 minutes
setInterval(() => serverCards.forEach(checkServerStatus), 5 * 60 * 1000);
});

34
html/js/theme-switcher.js Normal file
View File

@@ -0,0 +1,34 @@
document.addEventListener('DOMContentLoaded', () => {
const themeOptions = document.querySelectorAll('.theme-option');
const html = document.documentElement;
// Set initial theme from localStorage or default to latte
const savedTheme = localStorage.getItem('catppuccin-theme') || 'latte';
html.setAttribute('data-theme', savedTheme);
updateActiveTheme(savedTheme);
// Theme switcher functionality
themeOptions.forEach(option => {
option.addEventListener('click', () => {
const theme = option.dataset.theme;
html.setAttribute('data-theme', theme);
localStorage.setItem('catppuccin-theme', theme);
updateActiveTheme(theme);
});
});
// Update active theme indicator
function updateActiveTheme(theme) {
themeOptions.forEach(opt => {
const isActive = opt.dataset.theme === theme;
opt.classList.toggle('active', isActive);
// Update border color immediately
if (isActive) {
opt.style.borderColor = `var(--theme-mantle)`;
} else {
opt.style.borderColor = 'transparent';
}
});
}
});