// Fetch YouTube videos from API async function fetchVideos() { try { // Using a mock API since YouTube API requires authentication const response = await fetch('https://youtube-v31.p.rapidapi.com/search?q=music&part=snippet&maxResults=24', { method: 'GET', headers: { 'X-RapidAPI-Key': 'your-api-key', 'X-RapidAPI-Host': 'youtube-v31.p.rapidapi.com' } }); // Fallback to mock data if API fails if (!response.ok) { return getMockVideos(); } const data = await response.json(); return data.items; } catch (error) { console.error('Error fetching videos:', error); return getMockVideos(); } } // Mock data for fallback function getMockVideos() { return Array(12).fill().map((_, i) => ({ id: { videoId: `mock${i}` }, snippet: { title: `Awesome Video ${i + 1}`, channelTitle: `Channel ${i + 1}`, thumbnails: { medium: { url: `http://static.photos/technology/320x240/${i + 100}` } }, publishedAt: new Date().toISOString() } })); } // Render videos to the page async function renderVideos() { const videos = await fetchVideos(); const container = document.querySelector('main .grid'); videos.forEach((video, index) => { const videoCard = document.createElement('custom-video-card'); videoCard.setAttribute('video-id', video.id.videoId); videoCard.setAttribute('title', video.snippet.title); videoCard.setAttribute('channel', video.snippet.channelTitle); videoCard.setAttribute('thumbnail', video.snippet.thumbnails.medium.url); videoCard.setAttribute('published', video.snippet.publishedAt); videoCard.style.animationDelay = `${0.1 * (index % 8)}s`; container.appendChild(videoCard); }); } // Initialize the app document.addEventListener('DOMContentLoaded', () => { renderVideos(); setupMobileNavigation(); // Toggle dark mode const html = document.documentElement; const darkModeToggle = document.createElement('button'); darkModeToggle.innerHTML = ''; darkModeToggle.className = 'p-2 rounded-full hover:bg-gray-700'; darkModeToggle.addEventListener('click', () => { html.classList.toggle('dark'); feather.replace(); }); document.querySelector('custom-navbar').shadowRoot.querySelector('.right-section').appendChild(darkModeToggle); feather.replace(); }); // Mobile navigation setup function setupMobileNavigation() { const mobileMenuBtn = document.querySelector('custom-navbar').shadowRoot.querySelector('.mobile-menu-btn'); const sidebar = document.querySelector('custom-sidebar'); const overlay = sidebar.shadowRoot.querySelector('.overlay'); if (mobileMenuBtn && sidebar && overlay) { mobileMenuBtn.addEventListener('click', () => { const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); sidebarElement.classList.toggle('open'); overlay.classList.toggle('open'); }); overlay.addEventListener('click', () => { const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); sidebarElement.classList.remove('open'); overlay.classList.remove('open'); }); // Close sidebar when clicking on a sidebar item on mobile const sidebarItems = sidebar.shadowRoot.querySelectorAll('.sidebar-item'); sidebarItems.forEach(item => { item.addEventListener('click', () => { if (window.innerWidth < 768) { const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); sidebarElement.classList.remove('open'); overlay.classList.remove('open'); } }); }); } } // Responsive grid layout function updateGridLayout() { const container = document.querySelector('main .grid'); if (!container) return; if (window.innerWidth < 640) { container.className = 'grid grid-cols-1 gap-3 mobile-p-2'; } else if (window.innerWidth < 768) { container.className = 'grid grid-cols-2 gap-3'; } else if (window.innerWidth < 1024) { container.className = 'grid grid-cols-3 gap-4'; } else { container.className = 'grid grid-cols-4 gap-4'; } } // Listen for window resize window.addEventListener('resize', updateGridLayout); window.addEventListener('load', updateGridLayout);