anycoder-2884d574 / components /SpotifyDashboard.jsx
Det9999's picture
Upload components/SpotifyDashboard.jsx with huggingface_hub
4b58182 verified
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>
);
}