fediversion/frontend/components/recommendations/recommended-tracks.tsx
fullsizemalt 7b8ba4b54c
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
feat: User Personalization, Playlists, Recommendations, and DSO Importer
2025-12-29 16:28:43 -08:00

78 lines
3.4 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
import { Star, Music, PlayCircle } from "lucide-react"
import Link from "next/link"
import { getApiUrl } from "@/lib/api-config"
import { Skeleton } from "@/components/ui/skeleton"
import { AddToPlaylistDialog } from "@/components/playlists/add-to-playlist-dialog"
export function RecommendedTracks() {
const [tracks, setTracks] = useState<any[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
const token = localStorage.getItem("token")
if (!token) return
fetch(`${getApiUrl()}/recommendations/performances/top?limit=5`, {
headers: { Authorization: `Bearer ${token}` }
})
.then(res => res.json())
.then(data => setTracks(data))
.catch(err => console.error(err))
.finally(() => setLoading(false))
}, [])
if (loading) return <Skeleton className="h-48 w-full" />
if (tracks.length === 0) return null
return (
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-lg flex items-center gap-2">
<Star className="h-5 w-5 text-yellow-500" />
Top Rated Jams
</CardTitle>
<CardDescription>Fan favorites from your bands</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{tracks.map((track) => (
<div key={track.id} className="group flex items-center justify-between border-b last:border-0 pb-3 last:pb-0">
<div className="flex items-center gap-3 overflow-hidden">
<div className="bg-muted p-2 rounded-full">
<Music className="h-4 w-4 text-muted-foreground" />
</div>
<div className="min-w-0">
<p className="font-medium truncate">{track.song_title}</p>
<div className="text-xs text-muted-foreground flex gap-2">
<span>{track.vertical_name}</span>
<span></span>
<span>{track.show_date}</span>
</div>
</div>
</div>
<div className="flex items-center gap-2 pl-2">
<div className="text-right">
<span className="font-bold text-sm text-yellow-600 dark:text-yellow-400">
{track.avg_rating}
</span>
</div>
<div className="opacity-0 group-hover:opacity-100 transition-opacity">
<AddToPlaylistDialog
performanceId={track.id}
songTitle={track.song_title}
/>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
)
}