Move panel to website theme
This commit is contained in:
226
public/js/app.js
226
public/js/app.js
@@ -28,6 +28,137 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
'enable-status'
|
||||
];
|
||||
|
||||
const sections = document.querySelectorAll('.section-bg');
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, index) => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transitionDelay = `${index * 0.1}s`;
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1 });
|
||||
|
||||
// sections.forEach(section => {
|
||||
// section.style.transform = 'translateY(30px)';
|
||||
// section.style.opacity = '0';
|
||||
// section.style.transition = 'transform 0.7s ease-out, opacity 0.7s ease-out';
|
||||
// observer.observe(section);
|
||||
// });
|
||||
|
||||
// const PARTICLE_POOL_SIZE = 50;
|
||||
// const particlePool = [];
|
||||
// const activeParticles = new Set();
|
||||
|
||||
// function createParticleElement() {
|
||||
// const particle = document.createElement('div');
|
||||
// particle.classList.add('particle');
|
||||
// if (Math.random() > 0.6) particle.classList.add('large');
|
||||
// return particle;
|
||||
// }
|
||||
|
||||
// function initializeParticlePool() {
|
||||
// for (let i = 0; i < PARTICLE_POOL_SIZE; i++) {
|
||||
// particlePool.push(createParticleElement());
|
||||
// }
|
||||
// }
|
||||
|
||||
// function resetParticle(particle) {
|
||||
// particle.style.left = `${Math.random() * 100}%`;
|
||||
// particle.style.top = `${Math.random() * 100}%`;
|
||||
// particle.style.animationDelay = `${Math.random() * 8}s`;
|
||||
// particle.style.animationDuration = `${8 + Math.random() * 6}s`;
|
||||
// particle.classList.remove('fade-out');
|
||||
// return particle;
|
||||
// }
|
||||
|
||||
// function spawnParticle() {
|
||||
// if (particlePool.length === 0 || activeParticles.size >= PARTICLE_POOL_SIZE) return;
|
||||
|
||||
// const particle = resetParticle(particlePool.pop());
|
||||
// if (!particle.parentNode) document.body.appendChild(particle);
|
||||
// activeParticles.add(particle);
|
||||
|
||||
// setTimeout(() => {
|
||||
// particle.classList.add('fade-out');
|
||||
// setTimeout(() => {
|
||||
// activeParticles.delete(particle);
|
||||
// particlePool.push(particle);
|
||||
// }, 500);
|
||||
// }, 14000);
|
||||
// }
|
||||
|
||||
// function animate() {
|
||||
// if (Math.random() < 0.1) spawnParticle(); // Reduced spawn frequency
|
||||
// requestAnimationFrame(animate);
|
||||
// }
|
||||
|
||||
// // Initialize and start
|
||||
// setTimeout(() => {
|
||||
// initializeParticlePool();
|
||||
// animate();
|
||||
// }, 500);
|
||||
|
||||
function throttle(fn, wait) {
|
||||
let lastTime = 0;
|
||||
return function (...args) {
|
||||
const now = Date.now();
|
||||
if (now - lastTime >= wait) {
|
||||
fn.apply(this, args);
|
||||
lastTime = now;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// const buttons = document.querySelectorAll('.btn-minecraft');
|
||||
// buttons.forEach(button => {
|
||||
// button.addEventListener('mousemove', (e) => {
|
||||
// const rect = button.getBoundingClientRect();
|
||||
// const x = e.clientX - rect.left;
|
||||
// const y = e.clientY - rect.top;
|
||||
// button.style.setProperty('--x', `${x}px`);
|
||||
// button.style.setProperty('--y', `${y}px`);
|
||||
// });
|
||||
// });
|
||||
|
||||
// Hamburger Menu Toggle
|
||||
const hamburger = document.querySelector('.hamburger');
|
||||
const mobileNav = document.querySelector('[data-mobile-nav]');
|
||||
const navLinks = mobileNav.querySelectorAll('a');
|
||||
|
||||
// Debounce function to prevent rapid clicks
|
||||
function debounce(fn, wait) {
|
||||
let timeout;
|
||||
return function (...args) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => fn.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
hamburger.addEventListener('click', debounce(() => {
|
||||
console.log('Hamburger clicked, toggling menu');
|
||||
mobileNav.classList.toggle('active');
|
||||
hamburger.classList.toggle('active');
|
||||
}, 100));
|
||||
|
||||
navLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
console.log('Nav link clicked, closing menu');
|
||||
mobileNav.classList.remove('active');
|
||||
hamburger.classList.remove('active');
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!mobileNav.contains(e.target) && !hamburger.contains(e.target) && mobileNav.classList.contains('active')) {
|
||||
console.log('Clicked outside, closing menu');
|
||||
mobileNav.classList.remove('active');
|
||||
hamburger.classList.remove('active');
|
||||
}
|
||||
});
|
||||
const elements = {
|
||||
loginPage: document.getElementById('loginPage'),
|
||||
loginApiKey: document.getElementById('loginApiKey'),
|
||||
@@ -321,7 +452,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
terminal.clear();
|
||||
} else {
|
||||
terminal = new Terminal({
|
||||
rows: 8,
|
||||
rows: 22,
|
||||
fontSize: 14,
|
||||
fontFamily: 'monospace',
|
||||
theme: {
|
||||
@@ -1038,9 +1169,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
elements.loginPage.classList.remove('hidden');
|
||||
elements.mainContent.classList.add('hidden');
|
||||
elements.authControls.innerHTML = '<input id="apiKey" type="text" placeholder="Enter API Key" class="bg-gray-700 px-4 py-2 rounded text-white">';
|
||||
elements.apiKeyInput = document.getElementById('apiKey');
|
||||
elements.apiKeyInput.addEventListener('change', handleApiKeyChange);
|
||||
if (ws) {
|
||||
ws.close();
|
||||
ws = null;
|
||||
@@ -1069,13 +1198,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
elements.loginPage.classList.add('hidden');
|
||||
elements.mainContent.classList.remove('hidden');
|
||||
elements.authControls.innerHTML = '<button id="logoutBtn" class="bg-red-600 hover:bg-red-700 px-4 py-2 rounded">Logout</button>';
|
||||
const logoutBtn = document.getElementById('logoutBtn');
|
||||
if (logoutBtn) {
|
||||
logoutBtn.addEventListener('click', handleLogout);
|
||||
} else {
|
||||
console.error('Logout button not found after insertion');
|
||||
}
|
||||
// Verify buttons exist
|
||||
const logoutBtn = document.getElementById('logoutBtn');
|
||||
const mobileLogoutBtn = document.getElementById('mobileLogoutBtn');
|
||||
|
||||
if (logoutBtn) {
|
||||
console.log('Desktop logout button found');
|
||||
} else {
|
||||
console.error('Desktop logout button (#logoutBtn) not found');
|
||||
}
|
||||
|
||||
if (mobileLogoutBtn) {
|
||||
console.log('Mobile logout button found');
|
||||
} else {
|
||||
console.error('Mobile logout button (#mobileLogoutBtn) not found');
|
||||
}
|
||||
|
||||
// Remove any existing logout listeners to prevent duplicates
|
||||
document.removeEventListener('click', handleLogoutClick);
|
||||
|
||||
// Event delegation for logout buttons
|
||||
function handleLogoutClick(event) {
|
||||
if (event.target.id === 'logoutBtn' || event.target.id === 'mobileLogoutBtn') {
|
||||
console.log(`Logout button clicked: ${event.target.id}`);
|
||||
handleLogout();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', handleLogoutClick);
|
||||
|
||||
initializeCharts();
|
||||
initializeTerminal();
|
||||
}
|
||||
@@ -1095,6 +1246,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
showLoginPage();
|
||||
}
|
||||
|
||||
async function handleRefresh() {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
const key = `action-refresh`;
|
||||
const notification = showNotification('Refreshing server data...', 'loading', key);
|
||||
ws.send(JSON.stringify({ type: 'refresh' }));
|
||||
initializeTerminal();
|
||||
setTimeout(() => updateNotification(notification, 'Server data refreshed successfully', 'success', key), 1000);
|
||||
} else {
|
||||
showNotification('Not connected to server. Please log in.', 'error', 'ws-disconnected');
|
||||
}
|
||||
}
|
||||
|
||||
function updatePagination() {
|
||||
const totalPages = Math.max(1, Math.ceil(totalResults / resultsPerPage));
|
||||
elements.pagination.innerHTML = '';
|
||||
@@ -1687,7 +1850,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
switchContainer.className = 'relative inline-block';
|
||||
switchContainer.setAttribute('role', 'switch');
|
||||
switchContainer.setAttribute('aria-checked', value.toLowerCase());
|
||||
switchContainer.setAttribute('tabindex', '0');
|
||||
switchContainer.dataset.name = key;
|
||||
switchContainer.style.width = '40px';
|
||||
switchContainer.style.height = '24px';
|
||||
@@ -1918,7 +2080,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
});
|
||||
|
||||
elements.apiKeyInput.addEventListener('change', handleApiKeyChange);
|
||||
// elements.apiKeyInput.addEventListener('change', handleApiKeyChange);
|
||||
|
||||
elements.generateMyLinkBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
@@ -2065,6 +2227,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
elements.updateModsBtn.addEventListener('click', updateMods);
|
||||
|
||||
elements.closeUpdateModsBtn.addEventListener('click', () => {
|
||||
@@ -2177,4 +2341,42 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
showLoginPage();
|
||||
}
|
||||
window.showNotification = showNotification;
|
||||
|
||||
// Add this at the end of the document.addEventListener('DOMContentLoaded', ...) block
|
||||
function applyResponsiveStyles() {
|
||||
const sections = document.querySelectorAll('.section-bg');
|
||||
sections.forEach(section => {
|
||||
section.style.padding = window.innerWidth <= 640 ? '1rem' : window.innerWidth <= 768 ? '1.5rem' : '2rem';
|
||||
section.style.maxWidth = '100%';
|
||||
section.style.overflowX = 'hidden';
|
||||
});
|
||||
|
||||
const iframes = document.querySelectorAll('#sftpIframe');
|
||||
iframes.forEach(iframe => {
|
||||
iframe.style.height = window.innerWidth <= 640 ? '300px' : window.innerWidth <= 768 ? '400px' : '650px';
|
||||
iframe.style.minHeight = iframe.style.height;
|
||||
iframe.style.width = '100%';
|
||||
iframe.style.maxWidth = '100%';
|
||||
});
|
||||
|
||||
const canvases = document.querySelectorAll('#memoryMeter, #cpuMeter');
|
||||
canvases.forEach(canvas => {
|
||||
canvas.style.width = window.innerWidth <= 640 ? '80px' : window.innerWidth <= 768 ? '100px' : '150px';
|
||||
canvas.style.height = canvas.style.width;
|
||||
});
|
||||
|
||||
const terminals = document.querySelectorAll('#dockerLogsTerminal');
|
||||
terminals.forEach(terminal => {
|
||||
terminal.style.maxHeight = window.innerWidth <= 640 ? '7rem' : window.innerWidth <= 768 ? '8rem' : '12rem';
|
||||
});
|
||||
|
||||
const consoles = document.querySelectorAll('#consoleOutput');
|
||||
consoles.forEach(console => {
|
||||
console.style.height = window.innerWidth <= 640 ? '7rem' : window.innerWidth <= 768 ? '8rem' : '12rem';
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('resize', applyResponsiveStyles);
|
||||
|
||||
|
||||
});
|
Reference in New Issue
Block a user