Spaces:
Running
Running
| // Global JavaScript functions and utilities | |
| // Initialize Feather icons after page load | |
| document.addEventListener('DOMContentLoaded', () => { | |
| feather.replace(); | |
| }); | |
| // Mobile menu toggle | |
| function toggleMobileMenu() { | |
| const menu = document.querySelector('.mobile-menu'); | |
| if (menu) { | |
| menu.classList.toggle('hidden'); | |
| } | |
| } | |
| // Smooth scroll for anchor links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const target = document.querySelector(this.getAttribute('href')); | |
| if (target) { | |
| target.scrollIntoView({ | |
| behavior: 'smooth', | |
| block: 'start' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Add animation on scroll | |
| const observerOptions = { | |
| threshold: 0.1, | |
| rootMargin: '0px 0px -50px 0px' | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('animate-fade-in'); | |
| } | |
| }); | |
| }, observerOptions); | |
| // Observe all sections | |
| document.addEventListener('DOMContentLoaded', () => { | |
| document.querySelectorAll('section').forEach(section => { | |
| observer.observe(section); | |
| }); | |
| }); | |
| // Form validation helper | |
| function validateForm(formElement) { | |
| let isValid = true; | |
| const inputs = formElement.querySelectorAll('input[required], textarea[required], select[required]'); | |
| inputs.forEach(input => { | |
| if (!input.value.trim()) { | |
| isValid = false; | |
| input.classList.add('border-red-500'); | |
| } else { | |
| input.classList.remove('border-red-500'); | |
| } | |
| }); | |
| return isValid; | |
| } | |
| // Show notification | |
| function showNotification(message, type = 'success') { | |
| const notification = document.createElement('div'); | |
| notification.className = `fixed top-4 right-4 px-6 py-4 rounded-lg shadow-lg z-50 ${ | |
| type === 'success' ? 'bg-green-500 text-white' : 'bg-red-500 text-white' | |
| }`; | |
| notification.innerHTML = ` | |
| <div class="flex items-center"> | |
| <i data-feather="${type === 'success' ? 'check-circle' : 'alert-circle'}" class="w-5 h-5 mr-2"></i> | |
| <span>${message}</span> | |
| </div> | |
| `; | |
| document.body.appendChild(notification); | |
| feather.replace(); | |
| setTimeout(() => { | |
| notification.remove(); | |
| }, 5000); | |
| } |