Spaces:
Running
Running
| // Interactive elements for TN Medical Connect | |
| document.addEventListener('DOMContentLoaded', function () { | |
| // Initialize all interactive components | |
| initAnimations(); | |
| initCounters(); | |
| initCarousels(); | |
| initFlipCards(); | |
| initDarkMode(); | |
| initFilterSystem(); | |
| initScrollReveal(); | |
| initScrollToTop(); | |
| // Add event listeners for interactive features | |
| document.querySelectorAll('.collapsible-content').forEach(setupCollapsible); | |
| document.querySelectorAll('.tabs-container').forEach(setupTabs); | |
| }); | |
| // === SCROLL-BASED FADE-IN === | |
| function initScrollReveal() { | |
| const animatedElements = document.querySelectorAll('.fade-in, .fade-in-up, .fade-in-left, .fade-in-right'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('visible'); // ✅ USES .visible NOW | |
| observer.unobserve(entry.target); | |
| } | |
| }); | |
| }, { threshold: 0.1 }); | |
| animatedElements.forEach(element => { | |
| element.style.opacity = 0; | |
| observer.observe(element); | |
| }); | |
| } | |
| // === COUNTER ANIMATIONS === | |
| function initCounters() { | |
| const counterElements = document.querySelectorAll('.counter-animation'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const target = parseInt(entry.target.getAttribute('data-target'), 10); | |
| const duration = parseInt(entry.target.getAttribute('data-duration') || 2000, 10); | |
| let startTime = null; | |
| function updateCounter(timestamp) { | |
| if (!startTime) startTime = timestamp; | |
| const elapsed = timestamp - startTime; | |
| const progress = Math.min(elapsed / duration, 1); | |
| const currentCount = Math.floor(progress * target); | |
| entry.target.textContent = currentCount.toLocaleString(); | |
| if (progress < 1) { | |
| requestAnimationFrame(updateCounter); | |
| } | |
| } | |
| requestAnimationFrame(updateCounter); | |
| observer.unobserve(entry.target); | |
| } | |
| }); | |
| }, { threshold: 0.5 }); | |
| counterElements.forEach(el => observer.observe(el)); | |
| } | |
| // === TESTIMONIAL CAROUSELS === | |
| function initCarousels() { | |
| document.querySelectorAll('.testimonial-carousel').forEach(carousel => { | |
| const track = carousel.querySelector('.testimonial-track'); | |
| const slides = carousel.querySelectorAll('.testimonial-slide'); | |
| const dotsContainer = carousel.querySelector('.testimonial-navigation'); | |
| let currentIndex = 0; | |
| if (dotsContainer) { | |
| slides.forEach((_, index) => { | |
| const dot = document.createElement('div'); | |
| dot.classList.add('testimonial-dot'); | |
| if (index === 0) dot.classList.add('active'); | |
| dot.addEventListener('click', () => goToSlide(index)); | |
| dotsContainer.appendChild(dot); | |
| }); | |
| } | |
| const nextBtn = carousel.querySelector('.testimonial-next'); | |
| const prevBtn = carousel.querySelector('.testimonial-prev'); | |
| if (nextBtn) nextBtn.addEventListener('click', nextSlide); | |
| if (prevBtn) prevBtn.addEventListener('click', prevSlide); | |
| function nextSlide() { | |
| goToSlide((currentIndex + 1) % slides.length); | |
| } | |
| function prevSlide() { | |
| goToSlide((currentIndex - 1 + slides.length) % slides.length); | |
| } | |
| function goToSlide(index) { | |
| currentIndex = index; | |
| track.style.transform = `translateX(-${index * 100}%)`; | |
| carousel.querySelectorAll('.testimonial-dot').forEach((dot, i) => { | |
| dot.classList.toggle('active', i === index); | |
| }); | |
| } | |
| if (carousel.hasAttribute('data-auto-slide')) { | |
| const interval = parseInt(carousel.getAttribute('data-auto-slide'), 10) || 5000; | |
| setInterval(nextSlide, interval); | |
| } | |
| }); | |
| } | |
| // === FLIP CARDS === | |
| function initFlipCards() { | |
| document.querySelectorAll('.flip-card').forEach(card => { | |
| if (card.classList.contains('click-to-flip')) { | |
| card.addEventListener('click', function () { | |
| this.classList.toggle('flipped'); | |
| }); | |
| } | |
| }); | |
| } | |
| // === DARK MODE TOGGLE === | |
| function initDarkMode() { | |
| const darkModeToggle = document.getElementById('dark-mode-toggle'); | |
| if (!darkModeToggle) return; | |
| const prefersDarkMode = localStorage.getItem('darkMode') === 'true'; | |
| const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches; | |
| if (prefersDarkMode || (prefersDarkScheme && localStorage.getItem('darkMode') === null)) { | |
| document.body.classList.add('dark-mode'); | |
| darkModeToggle.checked = true; | |
| } | |
| darkModeToggle.addEventListener('change', function () { | |
| if (this.checked) { | |
| document.body.classList.add('dark-mode'); | |
| localStorage.setItem('darkMode', 'true'); | |
| } else { | |
| document.body.classList.remove('dark-mode'); | |
| localStorage.setItem('darkMode', 'false'); | |
| } | |
| }); | |
| } | |
| // === FILTERING SYSTEM === | |
| function initFilterSystem() { | |
| document.querySelectorAll('.filter-container').forEach(container => { | |
| const filterControls = container.querySelectorAll('.filter-control'); | |
| const filterItems = container.querySelectorAll('.filter-item'); | |
| filterControls.forEach(control => { | |
| control.addEventListener('click', function () { | |
| filterControls.forEach(c => c.classList.remove('active')); | |
| this.classList.add('active'); | |
| const filterValue = this.getAttribute('data-filter'); | |
| filterItems.forEach(item => { | |
| if (filterValue === 'all' || item.classList.contains(filterValue)) { | |
| item.style.display = ''; | |
| } else { | |
| item.style.display = 'none'; | |
| } | |
| }); | |
| }); | |
| }); | |
| }); | |
| } | |
| // === STAGGERED ELEMENTS + PROGRESS BARS === | |
| function initAnimations() { | |
| document.querySelectorAll('.stagger-fade-in').forEach(container => { | |
| const children = container.children; | |
| Array.from(children).forEach((child, index) => { | |
| child.style.opacity = 0; | |
| child.style.animation = `fadeIn 0.5s ease-out ${index * 0.1}s forwards`; | |
| }); | |
| }); | |
| document.querySelectorAll('.progress-bar').forEach(progressBar => { | |
| const fill = progressBar.querySelector('.progress-bar-fill'); | |
| const targetWidth = fill.getAttribute('data-width') || '0'; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| fill.style.width = targetWidth; | |
| observer.unobserve(entry.target); | |
| } | |
| }); | |
| }, { threshold: 0.5 }); | |
| observer.observe(progressBar); | |
| }); | |
| } | |
| // === COLLAPSIBLE SECTIONS === | |
| function setupCollapsible(container) { | |
| const header = container.querySelector('.collapsible-header'); | |
| const content = container.querySelector('.collapsible-body'); | |
| header.addEventListener('click', function () { | |
| container.classList.toggle('active'); | |
| content.style.maxHeight = container.classList.contains('active') | |
| ? content.scrollHeight + 'px' | |
| : 0; | |
| }); | |
| content.style.maxHeight = 0; | |
| } | |
| // === TABS === | |
| function setupTabs(container) { | |
| const tabButtons = container.querySelectorAll('.tab-button'); | |
| const tabContents = container.querySelectorAll('.tab-content'); | |
| tabButtons.forEach((button, index) => { | |
| button.addEventListener('click', function () { | |
| tabButtons.forEach(btn => btn.classList.remove('active')); | |
| tabContents.forEach(content => content.classList.remove('active')); | |
| button.classList.add('active'); | |
| tabContents[index].classList.add('active'); | |
| }); | |
| }); | |
| if (tabButtons.length > 0) { | |
| tabButtons[0].click(); | |
| } | |
| } | |
| // === SCROLL TO TOP BUTTON === | |
| function initScrollToTop() { | |
| const scrollTopBtn = document.getElementById('scroll-top-btn'); | |
| if (!scrollTopBtn) return; | |
| window.addEventListener('scroll', function () { | |
| if (window.pageYOffset > 300) { | |
| scrollTopBtn.classList.add('show'); | |
| } else { | |
| scrollTopBtn.classList.remove('show'); | |
| } | |
| }); | |
| scrollTopBtn.addEventListener('click', function () { | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| }); | |
| } | |