Det9999 commited on
Commit
4b58182
·
verified ·
1 Parent(s): 80fa8ac

Upload components/SpotifyDashboard.jsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/SpotifyDashboard.jsx +101 -0
components/SpotifyDashboard.jsx ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Music, Clock, User as UserIcon, Disc } from 'lucide-react';
2
+
3
+ export default function SpotifyDashboard({ userData, topTracks, topArtists }) {
4
+ if (!userData) {
5
+ return (
6
+ <div className="h-full flex items-center justify-center text-gray-500">
7
+ <p>Connect to Spotify to view insights</p>
8
+ </div>
9
+ );
10
+ }
11
+
12
+ return (
13
+ <div className="space-y-6 h-full overflow-y-auto pr-2">
14
+ {/* Profile Card */}
15
+ <div className="bg-gradient-to-br from-[#333] to-[#181818] rounded-xl p-6 border border-white/10 shadow-lg">
16
+ <div className="flex items-center gap-4">
17
+ {userData.images && userData.images.length > 0 ? (
18
+ <img
19
+ src={userData.images[0]?.url}
20
+ alt={userData.display_name}
21
+ className="w-20 h-20 rounded-full shadow-lg border-2 border-black/50"
22
+ />
23
+ ) : (
24
+ <div className="w-20 h-20 rounded-full bg-gray-700 flex items-center justify-center">
25
+ <UserIcon className="w-10 h-10 text-gray-400" />
26
+ </div>
27
+ )}
28
+ <div>
29
+ <p className="text-sm font-semibold text-gray-400">Profile</p>
30
+ <h2 className="text-2xl font-bold">{userData.display_name}</h2>
31
+ <div className="flex items-center gap-3 mt-2 text-sm text-gray-300">
32
+ <span className="bg-white/10 px-2 py-0.5 rounded text-xs">
33
+ {userData.product === 'premium' ? 'Premium' : 'Free'}
34
+ </span>
35
+ <span>{Math.floor(userData.followers?.total / 1000)}k Followers</span>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ {/* Top Tracks */}
42
+ <div>
43
+ <h3 className="text-lg font-bold mb-4 flex items-center gap-2">
44
+ <Music className="w-5 h-5 text-spotify-green" />
45
+ Top Tracks
46
+ </h3>
47
+ <div className="space-y-2">
48
+ {topTracks?.slice(0, 5).map((track, index) => (
49
+ <div
50
+ key={track.id}
51
+ className="flex items-center gap-3 p-3 rounded-lg hover:bg-white/10 group transition-colors cursor-pointer"
52
+ >
53
+ <span className="text-gray-500 w-4 text-center font-mono text-sm">{index + 1}</span>
54
+ <img
55
+ src={track.album.images[0]?.url}
56
+ alt={track.name}
57
+ className="w-10 h-10 rounded shadow-md"
58
+ />
59
+ <div className="flex-1 min-w-0">
60
+ <p className="font-medium text-sm truncate group-hover:text-spotify-green transition-colors">
61
+ {track.name}
62
+ </p>
63
+ <p className="text-xs text-gray-400 truncate">
64
+ {track.artists.map(a => a.name).join(', ')}
65
+ </p>
66
+ </div>
67
+ <div className="text-xs text-gray-500 flex items-center gap-1">
68
+ <Clock className="w-3 h-3" />
69
+ {Math.floor(track.duration_ms / 60000)}:{(track.duration_ms % 60000 / 1000).toFixed(0).padStart(2, '0')}
70
+ </div>
71
+ </div>
72
+ ))}
73
+ </div>
74
+ </div>
75
+
76
+ {/* Top Artists */}
77
+ <div>
78
+ <h3 className="text-lg font-bold mb-4 flex items-center gap-2">
79
+ <Disc className="w-5 h-5 text-purple-400" />
80
+ Top Artists
81
+ </h3>
82
+ <div className="grid grid-cols-2 gap-3">
83
+ {topArtists?.slice(0, 4).map((artist) => (
84
+ <div
85
+ key={artist.id}
86
+ className="bg-white/5 rounded-lg p-3 hover:bg-white/10 transition-colors text-center"
87
+ >
88
+ <img
89
+ src={artist.images[0]?.url}
90
+ alt={artist.name}
91
+ className="w-full aspect-square object-cover rounded-md shadow-md mb-2"
92
+ />
93
+ <p className="font-medium text-sm truncate">{artist.name}</p>
94
+ <p className="text-[10px] text-gray-400 capitalize">{artist.genres?.slice(0, 2).join(', ')}</p>
95
+ </div>
96
+ ))}
97
+ </div>
98
+ </div>
99
+ </div>
100
+ );
101
+ }