let allSponsors = []; let grandTotal = 0; let filterState = { search: '', project: 'all' }; document.addEventListener('DOMContentLoaded', () => { try { setupUI(); } catch (e) { console.error("UI Setup failed", e); } fetchSponsorsData(); setupListeners(); }); function setupUI() { // Mobile menu toggle handled by components.js // Modal Logic const modal = document.getElementById('sponsor-modal'); const btn = document.getElementById('open-sponsor-modal'); const span = document.querySelector('.close-modal'); const desktopView = document.getElementById('desktop-qr-view'); const mobileView = document.getElementById('mobile-btn-view'); // Detect Mobile const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth < 768; if (isMobile) { if(desktopView) desktopView.style.display = 'none'; if(mobileView) mobileView.style.display = 'block'; } else { if(desktopView) desktopView.style.display = 'block'; if(mobileView) mobileView.style.display = 'none'; } if (modal && btn) { btn.addEventListener('click', (e) => { e.preventDefault(); modal.style.display = "flex"; // Trigger reflow void modal.offsetWidth; requestAnimationFrame(() => { modal.classList.add('show'); }); }); } if (span && modal) { span.addEventListener('click', () => { modal.classList.remove('show'); setTimeout(() => { modal.style.display = "none"; }, 300); }); } window.addEventListener('click', (event) => { if (modal && event.target == modal) { modal.classList.remove('show'); setTimeout(() => { modal.style.display = "none"; }, 300); } }); } function setupListeners() { const searchInput = document.getElementById('sponsor-search'); const filterContainer = document.getElementById('project-filters'); if (searchInput) { searchInput.addEventListener('input', (e) => { filterState.search = e.target.value.toLowerCase().trim(); applyFilters(); }); } if (filterContainer) { filterContainer.addEventListener('click', (e) => { if (e.target.classList.contains('filter-tag')) { // Update active class document.querySelectorAll('.filter-tag').forEach(btn => btn.classList.remove('active')); e.target.classList.add('active'); // Update filter state filterState.project = e.target.dataset.project; applyFilters(); } }); } } async function fetchSponsorsData() { try { const response = await fetch('data/sponsors.txt'); if (!response.ok) { throw new Error('Failed to fetch data/sponsors.txt'); } const text = await response.text(); const sponsors = DataUtils.parseSponsorsText(text); const projects = new Set(); grandTotal = 0; sponsors.forEach(item => { grandTotal += item.amount; projects.add(item.project); }); allSponsors = [...sponsors].reverse(); // Start with newest // Animate Total animateValue(grandTotal); // Render everything renderFilters(Array.from(projects)); applyFilters(); // Renders the grid initially } catch (error) { console.error('Error loading sponsors:', error); const grid = document.getElementById('donation-list'); if(grid) grid.innerHTML = '