78 lines
3.4 KiB
TypeScript
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>
|
|
)
|
|
}
|