Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Playlists - GrooveWave</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/howler@2.2.3/dist/howler.min.js"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%); | |
| color: #f7fafc; | |
| overflow-x: hidden; | |
| } | |
| .player-bar { | |
| background: rgba(26, 32, 44, 0.95); | |
| backdrop-filter: blur(10px); | |
| border-top: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .track-progress { | |
| appearance: none; | |
| height: 4px; | |
| border-radius: 2px; | |
| background: rgba(255, 255, 255, 0.2); | |
| } | |
| .track-progress::-webkit-slider-thumb { | |
| appearance: none; | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| background: #6366f1; | |
| cursor: pointer; | |
| } | |
| .album-art { | |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); | |
| transition: transform 0.3s ease; | |
| } | |
| .album-art:hover { | |
| transform: scale(1.05); | |
| } | |
| .playlist-item:hover { | |
| background: rgba(79, 70, 229, 0.2); | |
| } | |
| .nav-item.active { | |
| background: rgba(79, 70, 229, 0.3); | |
| border-left: 3px solid #6366f1; | |
| } | |
| .pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.4); } | |
| 70% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); } | |
| } | |
| </style> | |
| </head> | |
| <body class="h-screen flex flex-col"> | |
| <!-- Main Content --> | |
| <div class="flex flex-1 overflow-hidden"> | |
| <!-- Sidebar --> | |
| <div class="w-64 bg-gray-900 p-5 flex flex-col hidden md:flex"> | |
| <div class="mb-10"> | |
| <h1 class="text-2xl font-bold text-indigo-400 flex items-center"> | |
| <i data-feather="music" class="mr-2"></i> GrooveWave | |
| </h1> | |
| </div> | |
| <nav class="flex-1"> | |
| <ul class="space-y-2"> | |
| <li> | |
| <a href="index.html" class="nav-item flex items-center p-3 rounded-lg text-gray-400 hover:text-white"> | |
| <i data-feather="home" class="mr-3"></i> Home | |
| </a> | |
| </li> | |
| <li> | |
| <a href="search.html" class="nav-item flex items-center p-3 rounded-lg text-gray-400 hover:text-white"> | |
| <i data-feather="search" class="mr-3"></i> Search | |
| </a> | |
| </li> | |
| <li> | |
| <a href="favorites.html" class="nav-item flex items-center p-3 rounded-lg text-gray-400 hover:text-white"> | |
| <i data-feather="heart" class="mr-3"></i> Favorites | |
| </a> | |
| </li> | |
| <li> | |
| <a href="playlists.html" class="nav-item active flex items-center p-3 rounded-lg text-indigo-300"> | |
| <i data-feather="book" class="mr-3"></i> Playlists | |
| </a> | |
| </li> | |
| <li> | |
| <a href="radio.html" class="nav-item flex items-center p-3 rounded-lg text-gray-400 hover:text-white"> | |
| <i data-feather="radio" class="mr-3"></i> Radio | |
| </a> | |
| </li> | |
| </ul> | |
| <div class="mt-10"> | |
| <h3 class="text-gray-500 text-sm uppercase font-semibold mb-3">Your Playlists</h3> | |
| <ul class="space-y-2"> | |
| <li> | |
| <a href="playlist.html?id=1" class="text-gray-400 hover:text-white block py-2">Chill Vibes</a> | |
| </li> | |
| <li> | |
| <a href="playlist.html?id=2" class="text-gray-400 hover:text-white block py-2">Workout Mix</a> | |
| </li> | |
| <li> | |
| <a href="playlist.html?id=3" class="text-gray-400 hover:text-white block py-2">Road Trip</a> | |
| </li> | |
| <li> | |
| <a href="playlist.html?id=4" class="text-gray-400 hover:text-white block py-2">Focus Time</a> | |
| </li> | |
| </ul> | |
| </div> | |
| </nav> | |
| <div class="mt-auto pt-5 border-t border-gray-800"> | |
| <div class="flex items-center"> | |
| <div class="bg-gray-200 border-2 border-dashed rounded-xl w-10 h-10" /> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium">Alex Morgan</p> | |
| <p class="text-xs text-gray-500">Premium User</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content Area --> | |
| <div class="flex-1 flex flex-col overflow-hidden"> | |
| <!-- Top Bar --> | |
| <div class="p-5 bg-gray-800 flex items-center justify-between"> | |
| <div class="flex items-center"> | |
| <button class="md:hidden mr-4 text-gray-400"> | |
| <i data-feather="menu"></i> | |
| </button> | |
| <div class="relative"> | |
| <input | |
| type="text" | |
| placeholder="Search music, artists, albums..." | |
| class="bg-gray-700 rounded-full py-2 px-4 pl-10 text-sm w-64 focus:outline-none focus:ring-2 focus:ring-indigo-500" | |
| id="search-input" | |
| > | |
| <i data-feather="search" class="absolute left-3 top-2.5 text-gray-500"></i> | |
| </div> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-full text-sm font-medium flex items-center"> | |
| <i data-feather="plus" class="mr-2"></i> Create Playlist | |
| </button> | |
| <div class="flex items-center"> | |
| <div class="bg-gray-200 border-2 border-dashed rounded-xl w-8 h-8" /> | |
| <span class="ml-2 text-sm font-medium hidden md:inline">Alex</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Content --> | |
| <div class="flex-1 overflow-y-auto p-5"> | |
| <!-- Playlists Header --> | |
| <div class="flex justify-between items-center mb-8"> | |
| <h1 class="text-3xl font-bold">Playlists</h1> | |
| <button class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-full text-sm font-medium flex items-center"> | |
| <i data-feather="plus" class="mr-2"></i> Create Playlist | |
| </button> | |
| </div> | |
| <!-- Featured Playlists --> | |
| <section class="mb-10"> | |
| <h2 class="text-2xl font-bold mb-5">Featured Playlists</h2> | |
| <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-5"> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/21" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Top Charts</h3> | |
| <p class="text-gray-500 text-sm">The hottest tracks right now</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/22" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">New Releases</h3> | |
| <p class="text-gray-500 text-sm">Fresh tracks this week</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/23" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Mood Booster</h3> | |
| <p class="text-gray-500 text-sm">Feel-good tracks to lift your spirits</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/24" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Chill Vibes</h3> | |
| <p class="text-gray-500 text-sm">Relaxing beats for your downtime</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/25" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Workout Mix</h3> | |
| <p class="text-gray-500 text-sm">High-energy tracks for your workout</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Your Playlists --> | |
| <section> | |
| <h2 class="text-2xl font-bold mb-5">Your Playlists</h2> | |
| <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-5"> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/1" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Chill Vibes</h3> | |
| <p class="text-gray-500 text-sm">Alex Morgan • 24 songs</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/2" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Workout Mix</h3> | |
| <p class="text-gray-500 text-sm">Alex Morgan • 18 songs</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/3" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Road Trip</h3> | |
| <p class="text-gray-500 text-sm">Alex Morgan • 32 songs</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/4" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Focus Time</h3> | |
| <p class="text-gray-500 text-sm">Alex Morgan • 15 songs</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition cursor-pointer"> | |
| <div class="relative mb-3"> | |
| <img src="http://static.photos/music/320x240/5" alt="Playlist" class="w-full rounded-lg album-art"> | |
| <button class="absolute bottom-2 right-2 bg-indigo-600 rounded-full p-2"> | |
| <i data-feather="play" class="text-white w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <h3 class="font-semibold">Party Mix</h3> | |
| <p class="text-gray-500 text-sm">Alex Morgan • 28 songs</p> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Player Bar --> | |
| <div class="player-bar p-4"> | |
| <div class="max-w-7xl mx-auto"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center w-1/4"> | |
| <img id="now-playing-art" src="http://static.photos/music/320x240/8" alt="Now Playing" class="w-16 h-16 rounded-lg"> | |
| <div class="ml-3"> | |
| <h4 id="now-playing-title" class="font-semibold">Blinding Lights</h4> | |
| <p id="now-playing-artist" class="text-gray-400 text-sm">The Weeknd</p> | |
| </div> | |
| <button class="ml-4 text-gray-400 hover:text-white" onclick="toggleFavorite()"> | |
| <i data-feather="heart" id="favorite-icon"></i> | |
| </button> | |
| </div> | |
| <div class="flex-1 flex flex-col items-center w-2/4"> | |
| <div class="flex items-center space-x-6"> | |
| <button class="text-gray-400 hover:text-white" onclick="toggleShuffle()"> | |
| <i data-feather="shuffle" id="shuffle-icon"></i> | |
| </button> | |
| <button class="text-gray-400 hover:text-white" onclick="previousTrack()"> | |
| <i data-feather="skip-back"></i> | |
| </button> | |
| <button class="bg-white text-gray-900 rounded-full p-2 hover:bg-gray-200" onclick="togglePlayPause()"> | |
| <i data-feather="play" id="play-pause-icon"></i> | |
| </button> | |
| <button class="text-gray-400 hover:text-white" onclick="nextTrack()"> | |
| <i data-feather="skip-forward"></i> | |
| </button> | |
| <button class="text-gray-400 hover:text-white" onclick="toggleRepeat()"> | |
| <i data-feather="repeat" id="repeat-icon"></i> | |
| </button> | |
| </div> | |
| <div class="w-full flex items-center mt-2"> | |
| <span id="current-time" class="text-xs text-gray-500 mr-2">0:00</span> | |
| <input type="range" min="0" max="100" value="0" class="track-progress flex-1" id="progress-bar"> | |
| <span id="total-time" class="text-xs text-gray-500 ml-2">0:00</span> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-end space-x-4 w-1/4"> | |
| <button class="text-gray-400 hover:text-white"> | |
| <i data-feather="list"></i> | |
| </button> | |
| <button class="text-gray-400 hover:text-white"> | |
| <i data-feather="volume-2"></i> | |
| </button> | |
| <input type="range" min="0" max="100" value="80" class="track-progress w-24" id="volume-control"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| feather.replace(); | |
| // Player functionality | |
| let isPlaying = false; | |
| let isShuffle = false; | |
| let isRepeat = false; | |
| let currentTrack = null; | |
| let sound = null; | |
| // Update player display | |
| function updatePlayerDisplay(title, artist, artUrl) { | |
| document.getElementById('now-playing-title').textContent = title; | |
| document.getElementById('now-playing-artist').textContent = artist; | |
| document.getElementById('now-playing-art').src = artUrl; | |
| } | |
| // Play a track | |
| function playTrack(title, artist, artUrl) { | |
| // Stop current sound if playing | |
| if (sound) { | |
| sound.stop(); | |
| } | |
| // Update player display | |
| updatePlayerDisplay(title, artist, artUrl); | |
| // Create new sound (using a placeholder audio file) | |
| sound = new Howl({ | |
| src: ['https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'], | |
| autoplay: true, | |
| onplay: function() { | |
| isPlaying = true; | |
| updatePlayPauseIcon(); | |
| updateProgress(); | |
| }, | |
| onpause: function() { | |
| isPlaying = false; | |
| updatePlayPauseIcon(); | |
| }, | |
| onend: function() { | |
| isPlaying = false; | |
| updatePlayPauseIcon(); | |
| } | |
| }); | |
| sound.play(); | |
| currentTrack = { title, artist, artUrl }; | |
| } | |
| // Toggle play/pause | |
| function togglePlayPause() { | |
| if (!sound) return; | |
| if (isPlaying) { | |
| sound.pause(); | |
| } else { | |
| sound.play(); | |
| } | |
| } | |
| // Update play/pause icon | |
| function updatePlayPauseIcon() { | |
| const icon = document.getElementById('play-pause-icon'); | |
| if (isPlaying) { | |
| icon.setAttribute('data-feather', 'pause'); | |
| } else { | |
| icon.setAttribute('data-feather', 'play'); | |
| } | |
| feather.replace(); | |
| } | |
| // Toggle shuffle | |
| function toggleShuffle() { | |
| isShuffle = !isShuffle; | |
| const icon = document.getElementById('shuffle-icon'); | |
| if (isShuffle) { | |
| icon.classList.add('text-indigo-400'); | |
| } else { | |
| icon.classList.remove('text-indigo-400'); | |
| } | |
| } | |
| // Toggle repeat | |
| function toggleRepeat() { | |
| isRepeat = !isRepeat; | |
| const icon = document.getElementById('repeat-icon'); | |
| if (isRepeat) { | |
| icon.classList.add('text-indigo-400'); | |
| } else { | |
| icon.classList.remove('text-indigo-400'); | |
| } | |
| } | |
| // Toggle favorite | |
| function toggleFavorite() { | |
| const icon = document.getElementById('favorite-icon'); | |
| if (icon.getAttribute('data-feather') === 'heart') { | |
| icon.setAttribute('data-feather', 'heart-fill'); | |
| icon.classList.add('text-red-500'); | |
| } else { | |
| icon.setAttribute('data-feather', 'heart'); | |
| icon.classList.remove('text-red-500'); | |
| } | |
| feather.replace(); | |
| } | |
| // Next track | |
| function nextTrack() { | |
| // For demo purposes, just restart the current track | |
| if (sound) { | |
| sound.seek(0); | |
| } | |
| } | |
| // Previous track | |
| function previousTrack() { | |
| // For demo purposes, just restart the current track | |
| if (sound) { | |
| sound.seek(0); | |
| } | |
| } | |
| // Update progress bar | |
| function updateProgress() { | |
| if (!sound) return; | |
| const progressBar = document.getElementById('progress-bar'); | |
| const currentTime = document.getElementById('current-time'); | |
| const totalTime = document.getElementById('total-time'); | |
| // Format time helper | |
| function formatTime(seconds) { | |
| const min = Math.floor(seconds / 60); | |
| const sec = Math.floor(seconds % 60); | |
| return `${min}:${sec < 10 ? '0' : ''}${sec}`; | |
| } | |
| // Update progress while playing | |
| const update = () => { | |
| if (sound.playing()) { | |
| const seek = sound.seek() || 0; | |
| const duration = sound.duration(); | |
| progressBar.value = (seek / duration) * 100 || 0; | |
| currentTime.textContent = formatTime(seek); | |
| totalTime.textContent = formatTime(duration); | |
| requestAnimationFrame(update); | |
| } | |
| }; | |
| requestAnimationFrame(update); | |
| // Allow seeking | |
| progressBar.addEventListener('change', function() { | |
| const duration = sound.duration(); | |
| sound.seek(duration * (this.value / 100)); | |
| }); | |
| } | |
| // Volume control | |
| document.getElementById('volume-control').addEventListener('change', function() { | |
| if (sound) { | |
| sound.volume(this.value / 100); | |
| } | |
| }); | |
| // Search functionality | |
| document.getElementById('search-input').addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| alert(`Searching for: ${this.value}`); | |
| // In a real app, this would redirect to a search results page | |
| } | |
| }); | |
| // Initialize with a track | |
| window.addEventListener('load', function() { | |
| playTrack('Blinding Lights', 'The Weeknd', 'http://static.photos/music/320x240/8'); | |
| }); | |
| </script> | |
| </body> | |
| </html> |