Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Quran Recitation App</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Amiri:wght@400;700&family=Poppins:wght@300;400;500;600&display=swap'); | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background-color: #f5f5f5; | |
| } | |
| .arabic-font { | |
| font-family: 'Amiri', serif; | |
| font-size: 1.5rem; | |
| line-height: 2.5rem; | |
| } | |
| .player-container { | |
| background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%); | |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); | |
| } | |
| .surah-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); | |
| } | |
| .reciter-card { | |
| transition: all 0.3s ease; | |
| } | |
| .reciter-card:hover { | |
| background-color: #e0f2fe; | |
| } | |
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #f1f1f1; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #888; | |
| border-radius: 10px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #555; | |
| } | |
| /* Animation for loading */ | |
| @keyframes pulse { | |
| 0%, 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0.5; | |
| } | |
| } | |
| .animate-pulse { | |
| animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen bg-gray-50"> | |
| <!-- Header --> | |
| <header class="bg-indigo-900 text-white shadow-lg"> | |
| <div class="container mx-auto px-4 py-6 flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-quran text-3xl text-yellow-400"></i> | |
| <h1 class="text-2xl font-bold">Quran Recitation</h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button id="theme-toggle" class="p-2 rounded-full hover:bg-indigo-800"> | |
| <i class="fas fa-moon"></i> | |
| </button> | |
| <button class="bg-indigo-700 hover:bg-indigo-600 px-4 py-2 rounded-lg font-medium"> | |
| <i class="fas fa-bookmark mr-2"></i>Bookmarks | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="container mx-auto px-4 py-8"> | |
| <!-- Search Section --> | |
| <div class="mb-8"> | |
| <div class="relative max-w-2xl mx-auto"> | |
| <input type="text" placeholder="Search surah or reciter..." | |
| class="w-full px-6 py-4 rounded-full shadow-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <button class="absolute right-3 top-3 bg-indigo-600 text-white p-2 rounded-full hover:bg-indigo-700"> | |
| <i class="fas fa-search"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Player Section --> | |
| <div id="player-section" class="hidden player-container text-white rounded-xl p-6 mb-8 shadow-xl"> | |
| <div class="flex flex-col md:flex-row items-center justify-between"> | |
| <div class="flex items-center space-x-4 mb-4 md:mb-0"> | |
| <div class="w-16 h-16 bg-indigo-800 rounded-lg flex items-center justify-center"> | |
| <i class="fas fa-play text-2xl"></i> | |
| </div> | |
| <div> | |
| <h3 id="current-surah" class="text-xl font-bold">Al-Fatihah</h3> | |
| <p id="current-reciter" class="text-indigo-200">Mishary Rashid Alafasy</p> | |
| </div> | |
| </div> | |
| <audio id="audio-player" controls class="w-full md:w-2/3"> | |
| Your browser does not support the audio element. | |
| </audio> | |
| </div> | |
| <div class="mt-6 flex justify-between items-center"> | |
| <div class="flex space-x-4"> | |
| <button id="prev-btn" class="p-2 rounded-full bg-indigo-800 hover:bg-indigo-700"> | |
| <i class="fas fa-step-backward"></i> | |
| </button> | |
| <button id="play-btn" class="p-3 rounded-full bg-white text-indigo-900 hover:bg-gray-200"> | |
| <i class="fas fa-play"></i> | |
| </button> | |
| <button id="next-btn" class="p-2 rounded-full bg-indigo-800 hover:bg-indigo-700"> | |
| <i class="fas fa-step-forward"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <button class="p-2 rounded-full hover:bg-indigo-800"> | |
| <i class="fas fa-heart"></i> | |
| </button> | |
| <button class="p-2 rounded-full hover:bg-indigo-800"> | |
| <i class="fas fa-share-alt"></i> | |
| </button> | |
| <button class="p-2 rounded-full hover:bg-indigo-800"> | |
| <i class="fas fa-bookmark"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Tabs --> | |
| <div class="mb-8"> | |
| <div class="flex border-b border-gray-200"> | |
| <button id="surahs-tab" class="tab-button active px-6 py-3 font-medium text-indigo-700 border-b-2 border-indigo-700"> | |
| <i class="fas fa-list-ol mr-2"></i>Surahs | |
| </button> | |
| <button id="reciters-tab" class="tab-button px-6 py-3 font-medium text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-microphone-alt mr-2"></i>Reciters | |
| </button> | |
| <button id="juz-tab" class="tab-button px-6 py-3 font-medium text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-book-open mr-2"></i>Juz | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Surahs Content --> | |
| <div id="surahs-content" class="tab-content"> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <!-- Surah cards will be loaded here --> | |
| <div id="surahs-loading" class="col-span-3 flex justify-center py-12"> | |
| <div class="animate-pulse flex flex-col items-center"> | |
| <div class="h-12 w-12 bg-indigo-200 rounded-full mb-4"></div> | |
| <div class="h-4 w-32 bg-indigo-200 rounded mb-2"></div> | |
| <div class="h-4 w-24 bg-indigo-200 rounded"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Reciters Content --> | |
| <div id="reciters-content" class="tab-content hidden"> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6"> | |
| <!-- Reciter cards will be loaded here --> | |
| <div id="reciters-loading" class="col-span-4 flex justify-center py-12"> | |
| <div class="animate-pulse flex flex-col items-center"> | |
| <div class="h-12 w-12 bg-indigo-200 rounded-full mb-4"></div> | |
| <div class="h-4 w-32 bg-indigo-200 rounded mb-2"></div> | |
| <div class="h-4 w-24 bg-indigo-200 rounded"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Juz Content --> | |
| <div id="juz-content" class="tab-content hidden"> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4"> | |
| <!-- Juz cards will be loaded here --> | |
| <div id="juz-loading" class="col-span-6 flex justify-center py-12"> | |
| <div class="animate-pulse flex flex-col items-center"> | |
| <div class="h-12 w-12 bg-indigo-200 rounded-full mb-4"></div> | |
| <div class="h-4 w-32 bg-indigo-200 rounded mb-2"></div> | |
| <div class="h-4 w-24 bg-indigo-200 rounded"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="bg-gray-800 text-white py-8"> | |
| <div class="container mx-auto px-4"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-quran text-2xl text-yellow-400"></i> | |
| <span class="text-xl font-bold">Quran Recitation</span> | |
| </div> | |
| <p class="mt-2 text-gray-400">Listen to the Holy Quran with beautiful recitations</p> | |
| </div> | |
| <div class="flex space-x-6"> | |
| <a href="#" class="hover:text-yellow-400"><i class="fab fa-github text-xl"></i></a> | |
| <a href="#" class="hover:text-yellow-400"><i class="fab fa-twitter text-xl"></i></a> | |
| <a href="#" class="hover:text-yellow-400"><i class="fab fa-facebook text-xl"></i></a> | |
| <a href="#" class="hover:text-yellow-400"><i class="fas fa-envelope text-xl"></i></a> | |
| </div> | |
| </div> | |
| <div class="mt-8 pt-6 border-t border-gray-700 text-center text-gray-400"> | |
| <p>© 2023 Quran Recitation App. All rights reserved.</p> | |
| <p class="mt-2">Data sourced from quranicaudio-app repository</p> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| // DOM Elements | |
| const themeToggle = document.getElementById('theme-toggle'); | |
| const playerSection = document.getElementById('player-section'); | |
| const audioPlayer = document.getElementById('audio-player'); | |
| const playBtn = document.getElementById('play-btn'); | |
| const prevBtn = document.getElementById('prev-btn'); | |
| const nextBtn = document.getElementById('next-btn'); | |
| const currentSurah = document.getElementById('current-surah'); | |
| const currentReciter = document.getElementById('current-reciter'); | |
| // Tab elements | |
| const surahsTab = document.getElementById('surahs-tab'); | |
| const recitersTab = document.getElementById('reciters-tab'); | |
| const juzTab = document.getElementById('juz-tab'); | |
| const surahsContent = document.getElementById('surahs-content'); | |
| const recitersContent = document.getElementById('reciters-content'); | |
| const juzContent = document.getElementById('juz-content'); | |
| // Theme toggle | |
| themeToggle.addEventListener('click', () => { | |
| document.documentElement.classList.toggle('dark'); | |
| const icon = themeToggle.querySelector('i'); | |
| if (document.documentElement.classList.contains('dark')) { | |
| icon.classList.replace('fa-moon', 'fa-sun'); | |
| document.body.style.backgroundColor = '#1a202c'; | |
| } else { | |
| icon.classList.replace('fa-sun', 'fa-moon'); | |
| document.body.style.backgroundColor = '#f5f5f5'; | |
| } | |
| }); | |
| // Tab switching | |
| function switchTab(activeTab, activeContent) { | |
| // Remove active class from all tabs | |
| document.querySelectorAll('.tab-button').forEach(tab => { | |
| tab.classList.remove('active', 'text-indigo-700', 'border-indigo-700'); | |
| tab.classList.add('text-gray-500', 'hover:text-gray-700'); | |
| }); | |
| // Hide all content | |
| document.querySelectorAll('.tab-content').forEach(content => { | |
| content.classList.add('hidden'); | |
| }); | |
| // Activate selected tab | |
| activeTab.classList.add('active', 'text-indigo-700', 'border-indigo-700'); | |
| activeTab.classList.remove('text-gray-500', 'hover:text-gray-700'); | |
| // Show selected content | |
| activeContent.classList.remove('hidden'); | |
| } | |
| surahsTab.addEventListener('click', () => switchTab(surahsTab, surahsContent)); | |
| recitersTab.addEventListener('click', () => switchTab(recitersTab, recitersContent)); | |
| juzTab.addEventListener('click', () => switchTab(juzTab, juzContent)); | |
| // Audio player controls | |
| playBtn.addEventListener('click', () => { | |
| if (audioPlayer.paused) { | |
| audioPlayer.play(); | |
| playBtn.innerHTML = '<i class="fas fa-pause"></i>'; | |
| } else { | |
| audioPlayer.pause(); | |
| playBtn.innerHTML = '<i class="fas fa-play"></i>'; | |
| } | |
| }); | |
| audioPlayer.addEventListener('play', () => { | |
| playBtn.innerHTML = '<i class="fas fa-pause"></i>'; | |
| }); | |
| audioPlayer.addEventListener('pause', () => { | |
| playBtn.innerHTML = '<i class="fas fa-play"></i>'; | |
| }); | |
| // Load surahs data | |
| async function loadSurahs() { | |
| try { | |
| const response = await fetch('https://api.quran.com/api/v4/chapters?language=en'); | |
| const data = await response.json(); | |
| const surahsContainer = document.querySelector('#surahs-content .grid'); | |
| const loadingElement = document.getElementById('surahs-loading'); | |
| // Remove loading indicator | |
| if (loadingElement) { | |
| loadingElement.remove(); | |
| } | |
| // Create surah cards | |
| data.chapters.forEach(surah => { | |
| const surahCard = document.createElement('div'); | |
| surahCard.className = 'surah-card bg-white rounded-xl p-6 shadow-md hover:shadow-lg transition-all duration-300 cursor-pointer'; | |
| surahCard.innerHTML = ` | |
| <div class="flex items-start justify-between"> | |
| <div class="flex items-center"> | |
| <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center mr-4"> | |
| <span class="text-indigo-700 font-bold">${surah.id}</span> | |
| </div> | |
| <div> | |
| <h3 class="font-bold text-lg">${surah.name_simple}</h3> | |
| <p class="text-gray-500">${surah.translated_name.name}</p> | |
| </div> | |
| </div> | |
| <div class="text-right"> | |
| <p class="text-gray-500 text-sm">${surah.verses_count} verses</p> | |
| <p class="arabic-font text-indigo-700 mt-1">${surah.name_arabic}</p> | |
| </div> | |
| </div> | |
| `; | |
| surahCard.addEventListener('click', () => { | |
| // Show player section if hidden | |
| playerSection.classList.remove('hidden'); | |
| // Update current surah info | |
| currentSurah.textContent = surah.name_simple; | |
| currentReciter.textContent = 'Mishary Rashid Alafasy'; // Default reciter | |
| // Set audio source (using sample URL from quranicaudio-app) | |
| const surahNumber = surah.id.toString().padStart(3, '0'); | |
| audioPlayer.src = `https://download.quranicaudio.com/quran/mishary_rashid_alafasy/${surahNumber}.mp3`; | |
| // Play the surah | |
| audioPlayer.play(); | |
| }); | |
| surahsContainer.appendChild(surahCard); | |
| }); | |
| } catch (error) { | |
| console.error('Error loading surahs:', error); | |
| const loadingElement = document.getElementById('surahs-loading'); | |
| if (loadingElement) { | |
| loadingElement.innerHTML = ` | |
| <div class="text-center text-red-500"> | |
| <i class="fas fa-exclamation-triangle text-3xl mb-2"></i> | |
| <p>Failed to load surahs. Please try again later.</p> | |
| </div> | |
| `; | |
| } | |
| } | |
| } | |
| // Load reciters data | |
| async function loadReciters() { | |
| try { | |
| // Sample reciters data (in a real app, you would fetch from API) | |
| const reciters = [ | |
| { id: 1, name: "Mishary Rashid Alafasy", style: "Hafs", language: "Arabic" }, | |
| { id: 2, name: "Abdul Basit Abdul Samad", style: "Hafs", language: "Arabic" }, | |
| { id: 3, name: "Saad Al-Ghamdi", style: "Hafs", language: "Arabic" }, | |
| { id: 4, name: "Mahmoud Khalil Al-Hussary", style: "Hafs", language: "Arabic" }, | |
| { id: 5, name: "Muhammad Ayyub", style: "Hafs", language: "Arabic" }, | |
| { id: 6, name: "Abdullah Basfar", style: "Hafs", language: "Arabic" }, | |
| { id: 7, name: "Abdur-Rahman as-Sudais", style: "Hafs", language: "Arabic" }, | |
| { id: 8, name: "Maher Al Muaiqly", style: "Hafs", language: "Arabic" } | |
| ]; | |
| const recitersContainer = document.querySelector('#reciters-content .grid'); | |
| const loadingElement = document.getElementById('reciters-loading'); | |
| // Remove loading indicator | |
| if (loadingElement) { | |
| loadingElement.remove(); | |
| } | |
| // Create reciter cards | |
| reciters.forEach(reciter => { | |
| const reciterCard = document.createElement('div'); | |
| reciterCard.className = 'reciter-card bg-white rounded-xl p-6 shadow-md cursor-pointer'; | |
| reciterCard.innerHTML = ` | |
| <div class="flex items-center space-x-4"> | |
| <div class="w-14 h-14 rounded-full bg-indigo-100 flex items-center justify-center"> | |
| <i class="fas fa-microphone-alt text-indigo-700 text-xl"></i> | |
| </div> | |
| <div> | |
| <h3 class="font-bold">${reciter.name}</h3> | |
| <p class="text-gray-500 text-sm">${reciter.style} • ${reciter.language}</p> | |
| </div> | |
| </div> | |
| `; | |
| reciterCard.addEventListener('click', () => { | |
| // Show player section if hidden | |
| playerSection.classList.remove('hidden'); | |
| // Update current reciter info | |
| currentReciter.textContent = reciter.name; | |
| // If a surah is already selected, update the audio source with new reciter | |
| if (audioPlayer.src) { | |
| const surahNumber = audioPlayer.src.split('/').pop().split('.')[0]; | |
| audioPlayer.src = `https://download.quranicaudio.com/quran/${reciter.name.toLowerCase().replace(/ /g, '_')}/${surahNumber}.mp3`; | |
| audioPlayer.play(); | |
| } | |
| }); | |
| recitersContainer.appendChild(reciterCard); | |
| }); | |
| } catch (error) { | |
| console.error('Error loading reciters:', error); | |
| const loadingElement = document.getElementById('reciters-loading'); | |
| if (loadingElement) { | |
| loadingElement.innerHTML = ` | |
| <div class="text-center text-red-500"> | |
| <i class="fas fa-exclamation-triangle text-3xl mb-2"></i> | |
| <p>Failed to load reciters. Please try again later.</p> | |
| </div> | |
| `; | |
| } | |
| } | |
| } | |
| // Load juz data | |
| async function loadJuz() { | |
| try { | |
| // Sample juz data | |
| const juzList = Array.from({ length: 30 }, (_, i) => ({ | |
| id: i + 1, | |
| name: `Juz ${i + 1}`, | |
| surahRange: getJuzSurahRange(i + 1) | |
| })); | |
| const juzContainer = document.querySelector('#juz-content .grid'); | |
| const loadingElement = document.getElementById('juz-loading'); | |
| // Remove loading indicator | |
| if (loadingElement) { | |
| loadingElement.remove(); | |
| } | |
| // Create juz cards | |
| juzList.forEach(juz => { | |
| const juzCard = document.createElement('div'); | |
| juzCard.className = 'bg-white rounded-lg p-4 shadow-md text-center cursor-pointer hover:bg-indigo-50'; | |
| juzCard.innerHTML = ` | |
| <div class="w-12 h-12 rounded-full bg-indigo-100 flex items-center justify-center mx-auto mb-3"> | |
| <span class="text-indigo-700 font-bold">${juz.id}</span> | |
| </div> | |
| <h3 class="font-bold">${juz.name}</h3> | |
| <p class="text-gray-500 text-sm mt-1">${juz.surahRange}</p> | |
| `; | |
| juzCard.addEventListener('click', () => { | |
| alert(`Juz ${juz.id} selected. In a full implementation, this would load the juz recitation.`); | |
| }); | |
| juzContainer.appendChild(juzCard); | |
| }); | |
| } catch (error) { | |
| console.error('Error loading juz:', error); | |
| const loadingElement = document.getElementById('juz-loading'); | |
| if (loadingElement) { | |
| loadingElement.innerHTML = ` | |
| <div class="text-center text-red-500"> | |
| <i class="fas fa-exclamation-triangle text-3xl mb-2"></i> | |
| <p>Failed to load juz. Please try again later.</p> | |
| </div> | |
| `; | |
| } | |
| } | |
| } | |
| // Helper function to get juz surah range (simplified) | |
| function getJuzSurahRange(juzNumber) { | |
| // This is a simplified version - actual juz ranges would be more precise | |
| if (juzNumber <= 2) return 'Al-Fatihah - Al-Baqarah'; | |
| if (juzNumber <= 5) return 'Al-Imran - An-Nisa'; | |
| if (juzNumber <= 9) return 'Al-Ma\'idah - At-Tawbah'; | |
| if (juzNumber <= 12) return 'Yunus - Yusuf'; | |
| if (juzNumber <= 15) return 'Ar-Ra\'d - An-Nahl'; | |
| if (juzNumber <= 18) return 'Al-Isra\' - Al-Furqan'; | |
| if (juzNumber <= 21) return 'Ash-Shu\'ara\' - Al-Ahzab'; | |
| if (juzNumber <= 25) return 'Saba\' - Fussilat'; | |
| if (juzNumber <= 28) return 'Ash-Shura - Al-Hujurat'; | |
| return 'Qaf - An-Nas'; | |
| } | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', () => { | |
| loadSurahs(); | |
| loadReciters(); | |
| loadJuz(); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=rabah2025/quranicaudio" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |