forked from
chadtmiller.com/slices-teal-relay
Teal.fm frontend powered by slices.network
tealfm-slices.wisp.place
tealfm
slices
1interface Artist {
2 artistName: string;
3}
4
5interface ArtistItemProps {
6 artists: string | null | undefined;
7 count: number;
8 rank: number;
9 maxCount: number;
10}
11
12export default function ArtistItem({
13 artists,
14 count,
15 rank,
16 maxCount,
17}: ArtistItemProps) {
18 const barWidth = maxCount > 0 ? (count / maxCount) * 100 : 0;
19
20 // Parse artists JSON
21 let artistNames = "Unknown Artist";
22 if (artists) {
23 try {
24 const parsed = typeof artists === 'string' ? JSON.parse(artists) : artists;
25 if (Array.isArray(parsed)) {
26 artistNames = parsed.map((a: Artist) => a.artistName).join(", ");
27 } else if (typeof parsed === 'string') {
28 artistNames = parsed;
29 }
30 } catch (e) {
31 console.log('Failed to parse artists:', artists, e);
32 artistNames = String(artists);
33 }
34 }
35
36 return (
37 <div className="group py-3 px-4 hover:bg-zinc-900/50 transition-colors relative overflow-hidden">
38 <div
39 className="absolute inset-y-0 left-0 bg-violet-500/10 transition-all"
40 style={{ width: `${barWidth}%` }}
41 />
42 <div className="flex items-center gap-4 relative">
43 <div className="text-xs text-zinc-600 w-8 text-right flex-shrink-0 font-medium">
44 {rank}
45 </div>
46
47 <div className="flex-1 min-w-0">
48 <h3 className="text-sm font-medium text-zinc-100 truncate">
49 {artistNames}
50 </h3>
51 </div>
52
53 <div className="text-right flex-shrink-0">
54 <p className="text-xs text-zinc-400 font-medium">
55 {count.toLocaleString()}
56 </p>
57 </div>
58 </div>
59 </div>
60 );
61}