Files
web7sys/public/js/components.js
ben7sys 934aac41dc The dark/white mode functionality has been fixed for deployment with Coolify using Nixpacks. The improvements include:
Early theme initialization to prevent flashing
Proper component and script loading order
Enhanced error handling and fallbacks
Better theme state persistence
System theme preference detection
The theme system will now work correctly in the production environment when deployed through Coolify with Nixpacks build pack.
2024-11-15 10:15:18 +01:00

101 lines
3.7 KiB
JavaScript

// Custom event for when components are fully loaded
const COMPONENTS_LOADED_EVENT = 'componentsLoaded';
document.addEventListener('DOMContentLoaded', function() {
// Helper function to handle component loading
async function loadComponent(url, insertPosition) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.text();
document.body.insertAdjacentHTML(insertPosition, data);
// After header is loaded, initialize its event listeners
if (url.includes('header.html')) {
initializeHeader();
}
return true;
} catch (error) {
console.warn(`Failed to load component from ${url}:`, error);
return false;
}
}
// Load components with error handling
Promise.all([
loadComponent('components/header.html', 'afterbegin'),
loadComponent('components/footer.html', 'beforeend')
]).then(results => {
if (results.every(Boolean)) {
// Dispatch custom event when all components are loaded
document.dispatchEvent(new CustomEvent(COMPONENTS_LOADED_EVENT));
}
}).catch(error => {
console.warn('Error loading components:', error);
});
// Initialize header functionality after it's loaded
function initializeHeader() {
const header = document.querySelector('header');
if (!header) return;
const mobileMenuToggle = header.querySelector('.mobile-menu-toggle');
const navMenu = header.querySelector('.nav-menu');
// Mobile menu toggle
if (mobileMenuToggle && navMenu) {
mobileMenuToggle.addEventListener('click', () => {
navMenu.classList.toggle('active');
const menuIcon = mobileMenuToggle.querySelector('i');
if (menuIcon) {
menuIcon.className = navMenu.classList.contains('active')
? 'fas fa-times'
: 'fas fa-bars';
}
});
// Close menu when clicking outside
document.addEventListener('click', (e) => {
if (navMenu.classList.contains('active') &&
!e.target.closest('.nav-menu') &&
!e.target.closest('.mobile-menu-toggle')) {
navMenu.classList.remove('active');
const menuIcon = mobileMenuToggle.querySelector('i');
if (menuIcon) {
menuIcon.className = 'fas fa-bars';
}
}
});
}
// Scroll behavior
let lastScrollTop = 0;
let scrollTimeout;
window.addEventListener('scroll', () => {
if (scrollTimeout) {
window.cancelAnimationFrame(scrollTimeout);
}
scrollTimeout = window.requestAnimationFrame(() => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
// Don't hide header when near top of page
if (scrollTop < 100) {
header.style.transform = 'translateY(0)';
return;
}
// Hide header on scroll down, show on scroll up
if (scrollTop > lastScrollTop) {
header.style.transform = 'translateY(-100%)';
} else {
header.style.transform = 'translateY(0)';
}
lastScrollTop = scrollTop;
});
}, { passive: true });
}
});