Spaces:
Runtime error
Runtime error
| import { Music, Clock, User as UserIcon, Disc } from 'lucide-react'; | |
| export default function SpotifyDashboard({ userData, topTracks, topArtists }) { | |
| if (!userData) { | |
| return ( | |
| <div className="h-full flex items-center justify-center text-gray-500"> | |
| <p>Connect to Spotify to view insights</p> | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <div className="space-y-6 h-full overflow-y-auto pr-2"> | |
| {/* Profile Card */} | |
| <div className="bg-gradient-to-br from-[#333] to-[#181818] rounded-xl p-6 border border-white/10 shadow-lg"> | |
| <div className="flex items-center gap-4"> | |
| {userData.images && userData.images.length > 0 ? ( | |
| <img | |
| src={userData.images[0]?.url} | |
| alt={userData.display_name} | |
| className="w-20 h-20 rounded-full shadow-lg border-2 border-black/50" | |
| /> | |
| ) : ( | |
| <div className="w-20 h-20 rounded-full bg-gray-700 flex items-center justify-center"> | |
| <UserIcon className="w-10 h-10 text-gray-400" /> | |
| </div> | |
| )} | |
| <div> | |
| <p className="text-sm font-semibold text-gray-400">Profile</p> | |
| <h2 className="text-2xl font-bold">{userData.display_name}</h2> | |
| <div className="flex items-center gap-3 mt-2 text-sm text-gray-300"> | |
| <span className="bg-white/10 px-2 py-0.5 rounded text-xs"> | |
| {userData.product === 'premium' ? 'Premium' : 'Free'} | |
| </span> | |
| <span>{Math.floor(userData.followers?.total / 1000)}k Followers</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Top Tracks */} | |
| <div> | |
| <h3 className="text-lg font-bold mb-4 flex items-center gap-2"> | |
| <Music className="w-5 h-5 text-spotify-green" /> | |
| Top Tracks | |
| </h3> | |
| <div className="space-y-2"> | |
| {topTracks?.slice(0, 5).map((track, index) => ( | |
| <div | |
| key={track.id} | |
| className="flex items-center gap-3 p-3 rounded-lg hover:bg-white/10 group transition-colors cursor-pointer" | |
| > | |
| <span className="text-gray-500 w-4 text-center font-mono text-sm">{index + 1}</span> | |
| <img | |
| src={track.album.images[0]?.url} | |
| alt={track.name} | |
| className="w-10 h-10 rounded shadow-md" | |
| /> | |
| <div className="flex-1 min-w-0"> | |
| <p className="font-medium text-sm truncate group-hover:text-spotify-green transition-colors"> | |
| {track.name} | |
| </p> | |
| <p className="text-xs text-gray-400 truncate"> | |
| {track.artists.map(a => a.name).join(', ')} | |
| </p> | |
| </div> | |
| <div className="text-xs text-gray-500 flex items-center gap-1"> | |
| <Clock className="w-3 h-3" /> | |
| {Math.floor(track.duration_ms / 60000)}:{(track.duration_ms % 60000 / 1000).toFixed(0).padStart(2, '0')} | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Top Artists */} | |
| <div> | |
| <h3 className="text-lg font-bold mb-4 flex items-center gap-2"> | |
| <Disc className="w-5 h-5 text-purple-400" /> | |
| Top Artists | |
| </h3> | |
| <div className="grid grid-cols-2 gap-3"> | |
| {topArtists?.slice(0, 4).map((artist) => ( | |
| <div | |
| key={artist.id} | |
| className="bg-white/5 rounded-lg p-3 hover:bg-white/10 transition-colors text-center" | |
| > | |
| <img | |
| src={artist.images[0]?.url} | |
| alt={artist.name} | |
| className="w-full aspect-square object-cover rounded-md shadow-md mb-2" | |
| /> | |
| <p className="font-medium text-sm truncate">{artist.name}</p> | |
| <p className="text-[10px] text-gray-400 capitalize">{artist.genres?.slice(0, 2).join(', ')}</p> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |