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