Anthropic’s Claude Research Jukebox
Fourester’s Anthropic Jukebox
Copy and paste the code below into Anthropic’s Claude and ask Claude to reconstitute the jukebox from the code.
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Play, Pause, SkipForward, SkipBack, Plus, Trash2, Music, List, X } from 'lucide-react';
const PRELOADED_SONGS = [
{ id: 1, videoId: 'Ip9L8IvIsdQ', title: 'Donnie Iris - Ah! Leah!', url: 'https://www.youtube.com/watch?v=Ip9L8IvIsdQ' },
{ id: 2, videoId: 'SYqEgFEkxek', title: 'Don Felder - Heavy Metal (Takin\' a Ride)', url: 'https://www.youtube.com/watch?v=SYqEgFEkxek' },
{ id: 3, videoId: 'v2AC41dglnM', title: 'AC/DC - Thunderstruck', url: 'https://www.youtube.com/watch?v=v2AC41dglnM' },
{ id: 4, videoId: 'pAgnJDJN4VA', title: 'AC/DC - Back in Black', url: 'https://www.youtube.com/watch?v=pAgnJDJN4VA' },
{ id: 5, videoId: 'Ic02W1bWeFU', title: 'Foreigner - Jukebox Hero', url: 'https://www.youtube.com/watch?v=Ic02W1bWeFU' },
{ id: 6, videoId: 'jaiaaar88EM', title: 'Def Leppard - Hysteria', url: 'https://www.youtube.com/watch?v=jaiaaar88EM' },
{ id: 7, videoId: 'VdphvuyaV_I', title: 'Billy Idol - Rebel Yell', url: 'https://www.youtube.com/watch?v=VdphvuyaV_I' },
{ id: 8, videoId: '5W1WirHKz0U', title: 'Jay-Z - Can I Get A...', url: 'https://www.youtube.com/watch?v=5W1WirHKz0U' },
{ id: 9, videoId: 'TaG9SDxwPBg', title: 'Train - Calling All Angels', url: 'https://www.youtube.com/watch?v=TaG9SDxwPBg' },
{ id: 10, videoId: 'nhSdljm909Y', title: 'Def Leppard - Rock Of Ages', url: 'https://www.youtube.com/watch?v=nhSdljm909Y' },
{ id: 11, videoId: 'W2msh0jut2Y', title: 'Norman Greenbaum - Spirit In The Sky', url: 'https://www.youtube.com/watch?v=W2msh0jut2Y' },
{ id: 12, videoId: '4zAThXFOy2c', title: 'Chris Stapleton - Tennessee Whiskey', url: 'https://www.youtube.com/watch?v=4zAThXFOy2c&list=RD4zAThXFOy2c&start_radio=1' },
{ id: 13, videoId: 'tMDFv5m18Pw', title: 'Ozzy Osbourne - Crazy Train', url: 'https://www.youtube.com/watch?v=tMDFv5m18Pw' },
{ id: 14, videoId: 'rHqZBGHNgGE', title: 'AC/DC - Who Made Who', url: 'https://www.youtube.com/watch?v=rHqZBGHNgGE' },
{ id: 15, videoId: 'o1tj2zJ2Wvg', title: 'Guns N\' Roses - Welcome To The Jungle', url: 'https://www.youtube.com/watch?v=o1tj2zJ2Wvg&list=RDo1tj2zJ2Wvg&start_radio=1' },
{ id: 16, videoId: 'oEht5PbNWN4', title: 'Robert Johnson - Cross Road Blues', url: 'https://www.youtube.com/watch?v=oEht5PbNWN4&list=RDoEht5PbNWN4&start_radio=1' },
{ id: 17, videoId: '1aVHLL5egRY', title: 'Hootie & The Blowfish - Let Her Cry', url: 'https://www.youtube.com/watch?v=1aVHLL5egRY&list=RD1aVHLL5egRY&start_radio=1' },
{ id: 18, videoId: 'n6przeYW42M', title: 'Hollywood Vampires - Heroes', url: 'https://www.youtube.com/watch?v=n6przeYW42M&list=RDn6przeYW42M&start_radio=1' },
{ id: 19, videoId: 'ht38vtJJ8Tk', title: 'Bob Seger & The Silver Bullet Band - Strut', url: 'https://www.youtube.com/watch?v=ht38vtJJ8Tk&list=RDht38vtJJ8Tk&start_radio=1' },
{ id: 20, videoId: 'PTFwQP86BRs', title: 'Nine Inch Nails - Closer', url: 'https://www.youtube.com/watch?v=PTFwQP86BRs&list=RDPTFwQP86BRs&start_radio=1' },
{ id: 21, videoId: 'xwTPvcPYaOo', title: 'Fleetwood Mac - The Chain', url: 'https://www.youtube.com/watch?v=xwTPvcPYaOo&list=RDxwTPvcPYaOo&start_radio=1' },
{ id: 22, videoId: 'oIIxlgcuQRU', title: 'Yeah Yeah Yeahs - Maps', url: 'https://www.youtube.com/watch?v=oIIxlgcuQRU&list=RDoIIxlgcuQRU&start_radio=1' },
{ id: 23, videoId: '7Xf-Lesrkuc', title: 'Train - Drops Of Jupiter', url: 'https://www.youtube.com/watch?v=7Xf-Lesrkuc&list=RD7Xf-Lesrkuc&start_radio=1' },
{ id: 24, videoId: 'o9mJ82x_l-E', title: 'Filter - Hey Man Nice Shot', url: 'https://www.youtube.com/watch?v=o9mJ82x_l-E&list=RDo9mJ82x_l-E&start_radio=1' },
{ id: 25, videoId: 'DYd57rkvnpQ', title: 'Silversun Pickups - Lazy Eye', url: 'https://www.youtube.com/watch?v=DYd57rkvnpQ&list=RDDYd57rkvnpQ&start_radio=1' },
{ id: 26, videoId: 'z5rRZdiu1UE', title: 'Beastie Boys - Sabotage', url: 'https://www.youtube.com/watch?v=z5rRZdiu1UE' },
{ id: 27, videoId: 'iWOyfLBYtuU', title: 'Florence + The Machine - Dog Days Are Over', url: 'https://www.youtube.com/watch?v=iWOyfLBYtuU&list=RDiWOyfLBYtuU&start_radio=1' },
{ id: 28, videoId: '-CmadmM5cOk', title: 'Taylor Swift - Style', url: 'https://www.youtube.com/watch?v=-CmadmM5cOk&list=RD-CmadmM5cOk&start_radio=1' },
{ id: 29, videoId: 'p07GhDsZgz4', title: 'Melissa Etheridge - Like The Way I Do', url: 'https://www.youtube.com/watch?v=p07GhDsZgz4&list=RDp07GhDsZgz4&start_radio=1' },
{ id: 30, videoId: 'QwrbyH78wNM', title: 'Big Head Todd & The Monsters - Bittersweet', url: 'https://www.youtube.com/watch?v=QwrbyH78wNM' },
{ id: 31, videoId: '6Whgn_iE5uc', title: 'Santana - Smooth (feat. Rob Thomas)', url: 'https://www.youtube.com/watch?v=6Whgn_iE5uc' },
{ id: 32, videoId: 'Z-HLxpWGCzc', title: '10,000 Maniacs - These Are The Days', url: 'https://www.youtube.com/watch?v=Z-HLxpWGCzc&list=RDZ-HLxpWGCzc&start_radio=1' },
{ id: 33, videoId: 'Cwkej79U3ek', title: 'Vanessa Carlton - A Thousand Miles', url: 'https://www.youtube.com/watch?v=Cwkej79U3ek' },
{ id: 34, videoId: 'OOgpT5rEKIU', title: 'Alanis Morissette - Thank You', url: 'https://www.youtube.com/watch?v=OOgpT5rEKIU&list=RDOOgpT5rEKIU&start_radio=1' },
{ id: 35, videoId: 'glEiPXAYE-U', title: 'The Notorious B.I.G. - Hypnotize', url: 'https://www.youtube.com/watch?v=glEiPXAYE-U&list=RDglEiPXAYE-U&start_radio=1' },
{ id: 36, videoId: 'IYH7_GzP4Tg', title: 'Lil Jon & The East Side Boyz - Get Low', url: 'https://www.youtube.com/watch?v=IYH7_GzP4Tg&list=RDIYH7_GzP4Tg&start_radio=1' },
{ id: 37, videoId: 'FPoKiGQzbSQ', title: 'Missy Elliott - Get Ur Freak On', url: 'https://www.youtube.com/watch?v=FPoKiGQzbSQ&list=RDFPoKiGQzbSQ&start_radio=1' },
{ id: 38, videoId: 'H58vbez_m4E', title: 'Kendrick Lamar - Not Like Us', url: 'https://www.youtube.com/watch?v=H58vbez_m4E&list=RDH58vbez_m4E&start_radio=1' },
{ id: 39, videoId: 'QK8mJJJvaes', title: 'Macklemore & Ryan Lewis - Thrift Shop', url: 'https://www.youtube.com/watch?v=QK8mJJJvaes&list=RDQK8mJJJvaes&start_radio=1' },
{ id: 40, videoId: 'fx2Z5ZD_Rbo', title: 'Ying Yang Twins - Salt Shaker', url: 'https://www.youtube.com/watch?v=fx2Z5ZD_Rbo' },
{ id: 41, videoId: 'CBJtzEKetBM', title: 'Too $hort - Blow The Whistle', url: 'https://www.youtube.com/watch?v=CBJtzEKetBM&list=RDCBJtzEKetBM&start_radio=1' },
{ id: 42, videoId: 'xB-QQAM1GDM', title: 'Melissa Etheridge - I\'m The Only One', url: 'https://www.youtube.com/watch?v=xB-QQAM1GDM&list=RDxB-QQAM1GDM&start_radio=1' },
{ id: 43, videoId: 'LOZuxwVk7TU', title: 'Britney Spears - Toxic', url: 'https://www.youtube.com/watch?v=LOZuxwVk7TU&list=RDLOZuxwVk7TU&start_radio=1' },
{ id: 45, videoId: 'Kgjkth6BRRY', title: 'Gwen Stefani - Hollaback Girl', url: 'https://www.youtube.com/watch?v=Kgjkth6BRRY&list=RDKgjkth6BRRY&start_radio=1' },
{ id: 46, videoId: 'O-zpOMYRi0w', title: 'Iggy Azalea - Fancy (feat. Charli XCX)', url: 'https://www.youtube.com/watch?v=O-zpOMYRi0w&list=RDO-zpOMYRi0w&start_radio=1' },
{ id: 47, videoId: '9h30Bx4Klxg', title: 'Selena Gomez - Same Old Love', url: 'https://www.youtube.com/watch?v=9h30Bx4Klxg&list=RD9h30Bx4Klxg&start_radio=1' },
{ id: 48, videoId: 'FMlcn-_jpWY', title: 'Selena Gomez - Hands To Myself', url: 'https://www.youtube.com/watch?v=FMlcn-_jpWY&list=RDFMlcn-_jpWY&start_radio=1' },
{ id: 49, videoId: 'CvBfHwUxHIk', title: 'Rihanna - Umbrella (feat. Jay-Z)', url: 'https://www.youtube.com/watch?v=CvBfHwUxHIk' },
{ id: 50, videoId: '4kGvlESGvbs', title: 'Jennifer Lopez - Love Don\'t Cost A Thing', url: 'https://www.youtube.com/watch?v=4kGvlESGvbs&list=RD4kGvlESGvbs&start_radio=1' },
{ id: 51, videoId: '4Rg3sAb8Id8', title: 'Christina Aguilera - Dirty', url: 'https://www.youtube.com/watch?v=4Rg3sAb8Id8&list=RD4Rg3sAb8Id8&start_radio=1' },
{ id: 52, videoId: 'DPtfsk4ETjM', title: 'Jessica Simpson - These Boots Are Made For Walkin\'', url: 'https://www.youtube.com/watch?v=DPtfsk4ETjM&list=RDDPtfsk4ETjM&start_radio=1' },
{ id: 53, videoId: 'PstrAfoMKlc', title: 'Christina Aguilera - Fighter', url: 'https://www.youtube.com/watch?v=PstrAfoMKlc&list=RDPstrAfoMKlc&start_radio=1' },
{ id: 54, videoId: 'mW1dbiD_zDk', title: 'P!nk - Get The Party Started', url: 'https://www.youtube.com/watch?v=mW1dbiD_zDk&list=RDmW1dbiD_zDk&start_radio=1' },
{ id: 55, videoId: 'u4FF6MpcsRw', title: 'Britney Spears - Piece Of Me', url: 'https://www.youtube.com/watch?v=u4FF6MpcsRw&list=RDu4FF6MpcsRw&start_radio=1' },
{ id: 56, videoId: '3gOHvDP_vCs', title: 'Justin Timberlake - SexyBack', url: 'https://www.youtube.com/watch?v=3gOHvDP_vCs&list=RD3gOHvDP_vCs&start_radio=1' },
{ id: 57, videoId: '9SnxBvH-0Mc', title: 'Def Leppard - Foolin\'', url: 'https://www.youtube.com/watch?v=9SnxBvH-0Mc' },
{ id: 58, videoId: 'p13Cn0mONP8', title: 'Chris Stapleton - Bad As I Used To Be', url: 'https://www.youtube.com/watch?v=p13Cn0mONP8&list=RDp13Cn0mONP8&start_radio=1' },
{ id: 59, videoId: 'Jwtyn-L-2gQ', title: 'Rolling Stones - Sympathy For The Devil', url: 'https://www.youtube.com/watch?v=Jwtyn-L-2gQ&list=RDJwtyn-L-2gQ&start_radio=1' },
{ id: 60, videoId: 'vqdCZ0yHNa4', title: 'Free - All Right Now', url: 'https://www.youtube.com/watch?v=vqdCZ0yHNa4&list=RDvqdCZ0yHNa4&start_radio=1' },
{ id: 61, videoId: 'Z7OSSUwPVM4', title: 'Perfume Genius - Queen', url: 'https://www.youtube.com/watch?v=Z7OSSUwPVM4&list=RDZ7OSSUwPVM4&start_radio=1' }
];
export default function YouTubeJukebox() {
const [library, setLibrary] = useState(PRELOADED_SONGS);
const [queue, setQueue] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
const [volume, setVolume] = useState(50);
const [repeatMode, setRepeatMode] = useState(true);
const [error, setError] = useState(null);
const playerRef = useRef(null);
const [playerReady, setPlayerReady] = useState(false);
useEffect(() => {
loadLibrary();
}, []);
const loadLibrary = async () => {
try {
const result = await window.storage.get('jukebox-library');
if (result && result.value) {
const savedLibrary = JSON.parse(result.value);
setLibrary(savedLibrary);
console.log('Loaded library:', savedLibrary.length, 'songs');
}
} catch (error) {
console.log('No saved library, using preloaded songs:', error.message);
}
};
const saveLibrary = async (newLibrary) => {
try {
await window.storage.set('jukebox-library', JSON.stringify(newLibrary));
console.log('Library saved successfully');
} catch (error) {
console.error('Failed to save library:', error);
setError('Failed to save library. Changes may be lost.');
}
};
const removeFromLibrary = async (id) => {
try {
const updatedLibrary = library.filter(song => song.id !== id);
setLibrary(updatedLibrary);
await saveLibrary(updatedLibrary);
const updatedQueue = queue.filter(song => song.id !== id);
if (updatedQueue.length !== queue.length) {
setQueue(updatedQueue);
}
} catch (error) {
console.error('Error removing from library:', error);
setError('Failed to remove song from library.');
}
};
const addToQueue = (song) => {
setQueue(prev => [...prev, song]);
};
const playAll = () => {
setQueue([...library]);
setCurrentIndex(0);
setIsPlaying(true);
setTimeout(() => {
if (playerRef.current && playerReady) {
try {
playerRef.current.playVideo();
} catch (error) {
console.error('Error playing video:', error);
}
}
}, 1000);
};
const shuffleAndPlay = () => {
const shuffled = [...library].sort(() => Math.random() - 0.5);
setQueue(shuffled);
setCurrentIndex(0);
setIsPlaying(true);
setTimeout(() => {
if (playerRef.current && playerReady) {
try {
playerRef.current.playVideo();
} catch (error) {
console.error('Error playing video:', error);
}
}
}, 1000);
};
const removeFromQueue = (index) => {
const newQueue = queue.filter((_, i) => i !== index);
setQueue(newQueue);
if (index < currentIndex) {
setCurrentIndex(currentIndex - 1);
} else if (index === currentIndex) {
if (newQueue.length === 0) {
setCurrentIndex(0);
setIsPlaying(false);
} else if (index >= newQueue.length) {
setCurrentIndex(Math.max(0, newQueue.length - 1));
}
}
};
const skipForward = useCallback(() => {
setCurrentIndex(prevIndex => {
if (prevIndex < queue.length - 1) {
setTimeout(() => {
if (playerRef.current && playerReady) {
try {
playerRef.current.playVideo();
} catch (error) {
console.error('Error playing next video:', error);
}
}
}, 500);
return prevIndex + 1;
} else if (repeatMode) {
setTimeout(() => {
if (playerRef.current && playerReady) {
try {
playerRef.current.playVideo();
} catch (error) {
console.error('Error playing next video:', error);
}
}
}, 500);
return 0;
} else {
setIsPlaying(false);
return prevIndex;
}
});
}, [playerReady, repeatMode, queue.length]);
const skipBack = () => {
if (currentIndex > 0) {
setCurrentIndex(currentIndex - 1);
setTimeout(() => {
if (playerRef.current && playerReady && isPlaying) {
try {
playerRef.current.playVideo();
} catch (error) {
console.error('Error playing previous video:', error);
}
}
}, 500);
}
};
useEffect(() => {
if (window.YT && window.YT.Player) {
initializePlayer();
return;
}
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubeIframeAPIReady = initializePlayer;
function initializePlayer() {
try {
playerRef.current = new window.YT.Player('youtube-player', {
height: '315',
width: '560',
playerVars: {
autoplay: 0,
controls: 1,
},
events: {
onReady: () => {
console.log('Player ready');
setPlayerReady(true);
},
onStateChange: (event) => {
if (event.data === window.YT.PlayerState.ENDED) {
skipForward();
}
setIsPlaying(event.data === window.YT.PlayerState.PLAYING);
},
onError: (event) => {
console.error('Player error:', event.data);
setError('Video playback error. Skipping to next song...');
setTimeout(skipForward, 2000);
}
}
});
} catch (error) {
console.error('Failed to initialize player:', error);
setError('Failed to initialize video player.');
}
}
}, [skipForward]);
useEffect(() => {
if (playerReady && playerRef.current && queue[currentIndex]) {
try {
playerRef.current.loadVideoById(queue[currentIndex].videoId);
setTimeout(() => {
if (isPlaying && playerRef.current) {
playerRef.current.playVideo();
}
}, 100);
} catch (error) {
console.error('Error loading video:', error);
setError('Failed to load video.');
}
}
}, [currentIndex, queue, playerReady, isPlaying]);
useEffect(() => {
if (playerReady && playerRef.current) {
try {
playerRef.current.setVolume(volume);
} catch (error) {
console.error('Error setting volume:', error);
}
}
}, [volume, playerReady]);
const togglePlay = () => {
if (!playerRef.current || queue.length === 0) return;
try {
if (isPlaying) {
playerRef.current.pauseVideo();
} else {
playerRef.current.playVideo();
}
} catch (error) {
console.error('Error toggling playback:', error);
setError('Playback control error.');
}
};
const currentSong = queue[currentIndex];
return (
<div className="min-h-screen bg-gradient-to-br from-purple-900 via-pink-800 to-red-900 p-4">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-6">
<h1 className="text-6xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-yellow-300 via-pink-300 to-cyan-300 mb-2" style={{textShadow: '0 0 20px rgba(255,255,255,0.5)'}}>
🎵 Fourester Research Jukebox 🎵
</h1>
<p className="text-pink-200 text-lg">Your Personal Music Collection - {library.length} Songs Loaded! 🎵 AutoPlay Enabled ✓</p>
</div>
{error && (
<div className="bg-red-900 border-2 border-red-500 rounded-lg p-4 mb-4 flex items-center justify-between">
<p className="text-white">{error}</p>
<button onClick={() => setError(null)} className="text-white hover:text-red-200">
<X className="w-5 h-5" />
</button>
</div>
)}
<div className="bg-gradient-to-br from-slate-900 to-slate-800 rounded-3xl shadow-2xl border-4 border-yellow-400 overflow-hidden" style={{boxShadow: '0 0 40px rgba(250,204,21,0.4)'}}>
<div className="grid md:grid-cols-2 gap-4 p-6">
<div className="bg-slate-800 rounded-xl p-4 border-2 border-cyan-400" style={{boxShadow: '0 0 20px rgba(34,211,238,0.3)'}}>
<div className="flex items-center justify-between mb-4 flex-wrap gap-2">
<h2 className="text-2xl font-bold text-cyan-300 flex items-center gap-2">
<Music className="w-6 h-6" />
Your Library ({library.length} Songs)
</h2>
<div className="flex gap-2 flex-wrap">
<button
onClick={playAll}
disabled={library.length === 0}
className="px-4 py-2 bg-gradient-to-r from-green-500 to-emerald-600 text-white font-bold text-sm rounded-lg hover:from-green-400 hover:to-emerald-500 transition-all shadow-lg flex items-center gap-2 disabled:opacity-50"
title="Play All Songs"
>
<Play className="w-4 h-4" />
Play All
</button>
<button
onClick={shuffleAndPlay}
disabled={library.length === 0}
className="px-4 py-2 bg-gradient-to-r from-purple-500 to-pink-600 text-white font-bold text-sm rounded-lg hover:from-purple-400 hover:to-pink-500 transition-all shadow-lg disabled:opacity-50"
title="Shuffle & Play"
>
🔀 Shuffle
</button>
</div>
</div>
<div className="space-y-2 max-h-[600px] overflow-y-auto">
{library.length === 0 ? (
<p className="text-gray-400 text-center py-8">No songs in library.</p>
) : (
library.map((song, index) => (
<div key={song.id} className="bg-slate-700 p-3 rounded-lg hover:bg-slate-600 transition-colors">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2 flex-1 min-w-0">
<span className="text-cyan-400 font-bold text-sm">{index + 1}.</span>
<p className="text-white font-medium text-sm truncate">{song.title}</p>
</div>
<div className="flex gap-2 ml-2">
<button
onClick={() => addToQueue(song)}
className="p-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors"
title="Add to Queue"
>
<Plus className="w-4 h-4" />
</button>
<button
onClick={() => removeFromLibrary(song.id)}
className="p-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
title="Remove from Library"
>
<Trash2 className="w-4 h-4" />
</button>
</div>
</div>
<a
href={song.url}
target="_blank"
rel="noopener noreferrer"
className="text-xs text-blue-400 hover:text-blue-300 break-all"
>
🔗 {song.url}
</a>
</div>
))
)}
</div>
</div>
<div className="bg-slate-800 rounded-xl p-4 border-2 border-pink-400" style={{boxShadow: '0 0 20px rgba(236,72,153,0.3)'}}>
<h2 className="text-2xl font-bold text-pink-300 mb-4 flex items-center gap-2">
<List className="w-6 h-6" />
Play Queue ({queue.length})
</h2>
<div className="space-y-2 max-h-[600px] overflow-y-auto">
{queue.length === 0 ? (
<p className="text-gray-400 text-center py-8">Queue is empty. Add songs from your library!</p>
) : (
queue.map((song, index) => (
<div
key={`${song.id}-${index}`}
className={`p-3 rounded-lg flex items-center justify-between transition-colors ${
index === currentIndex
? 'bg-gradient-to-r from-pink-600 to-purple-600 border-2 border-yellow-400'
: 'bg-slate-700 hover:bg-slate-600'
}`}
>
<div className="flex items-center gap-3 flex-1 min-w-0">
<span className="text-lg font-bold text-yellow-300">
{index === currentIndex ? '▶' : index + 1}
</span>
<p className="text-white font-medium text-sm truncate">{song.title}</p>
</div>
<button
onClick={() => removeFromQueue(index)}
className="p-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors ml-2"
title="Remove from Queue"
>
<X className="w-4 h-4" />
</button>
</div>
))
)}
</div>
</div>
</div>
<div className="bg-gradient-to-r from-slate-900 to-slate-800 p-6 border-t-4 border-yellow-400">
{currentSong && (
<div className="text-center mb-4">
<p className="text-sm text-pink-300 uppercase tracking-wide">Now Playing</p>
<h3 className="text-3xl font-bold text-yellow-300 mb-2">{currentSong.title}</h3>
</div>
)}
<div className="flex justify-center mb-6">
<div className="bg-black rounded-lg overflow-hidden border-4 border-cyan-400" style={{boxShadow: '0 0 30px rgba(34,211,238,0.5)'}}>
<div id="youtube-player"></div>
</div>
</div>
<div className="flex items-center justify-center gap-4 mb-4">
<button
onClick={skipBack}
disabled={queue.length === 0 || currentIndex === 0}
className="p-4 bg-gradient-to-br from-cyan-500 to-blue-600 text-white rounded-full hover:from-cyan-400 hover:to-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-lg"
>
<SkipBack className="w-6 h-6" />
</button>
<button
onClick={togglePlay}
disabled={queue.length === 0}
className="p-6 bg-gradient-to-br from-pink-500 to-purple-600 text-white rounded-full hover:from-pink-400 hover:to-purple-500 disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-xl"
style={{boxShadow: '0 0 30px rgba(236,72,153,0.6)'}}
>
{isPlaying ? <Pause className="w-8 h-8" /> : <Play className="w-8 h-8" />}
</button>
<button
onClick={skipForward}
disabled={queue.length === 0}
className="p-4 bg-gradient-to-br from-cyan-500 to-blue-600 text-white rounded-full hover:from-cyan-400 hover:to-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-lg"
>
<SkipForward className="w-6 h-6" />
</button>
</div>
<div className="flex items-center justify-center gap-3 max-w-md mx-auto mb-4">
<span className="text-yellow-300 font-bold">🔊</span>
<input
type="range"
min="0"
max="100"
value={volume}
onChange={(e) => setVolume(parseInt(e.target.value))}
className="flex-1 accent-pink-500"
/>
<span className="text-yellow-300 font-bold w-12 text-right">{volume}%</span>
</div>
<div className="flex items-center justify-center gap-4 flex-wrap">
<button
onClick={() => setRepeatMode(!repeatMode)}
className={`px-4 py-2 rounded-lg font-semibold transition-all ${
repeatMode
? 'bg-gradient-to-r from-green-500 to-emerald-600 text-white shadow-lg'
: 'bg-slate-700 text-gray-400 hover:bg-slate-600'
}`}
title={repeatMode ? "Repeat: ON (playlist will loop)" : "Repeat: OFF (stops after last song)"}
>
🔁 Repeat: {repeatMode ? 'ON' : 'OFF'}
</button>
<div className="text-cyan-300 font-semibold">
▶️ AutoPlay Enabled
</div>
{!playerReady && (
<div className="text-yellow-300 text-sm">
Loading player...
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
}