Teal.fm frontend powered by slices.network tealfm-slices.wisp.place
tealfm slices
at main 1.6 kB view raw
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}