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' }); | |
}); | |
} | |