82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
'use client'
|
|
|
|
export interface PlaylistCardProps {
|
|
id: string
|
|
title: string
|
|
description?: string
|
|
coverUrl?: string
|
|
songCount: number
|
|
isPublic?: boolean
|
|
onClick?: () => void
|
|
}
|
|
|
|
export function PlaylistCard({
|
|
id,
|
|
title,
|
|
description,
|
|
coverUrl,
|
|
songCount,
|
|
isPublic = false,
|
|
onClick
|
|
}: PlaylistCardProps) {
|
|
return (
|
|
<div
|
|
className="group bg-zinc-900 rounded-lg p-4 hover:bg-zinc-800 transition cursor-pointer"
|
|
onClick={onClick}
|
|
>
|
|
{/* Cover Image */}
|
|
<div className="relative aspect-square rounded-md overflow-hidden mb-4 bg-zinc-800">
|
|
{coverUrl ? (
|
|
<img
|
|
src={coverUrl}
|
|
alt={title}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
|
/>
|
|
) : (
|
|
<div className="w-full h-full flex items-center justify-center">
|
|
<svg className="w-16 h-16 text-zinc-600" fill="currentColor" viewBox="0 0 20 20">
|
|
<path d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z" />
|
|
</svg>
|
|
</div>
|
|
)}
|
|
|
|
{/* Play Button Overlay */}
|
|
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/40 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all">
|
|
<button className="w-14 h-14 rounded-full bg-purple-500 hover:bg-purple-600 hover:scale-110 flex items-center justify-center transition-transform">
|
|
<svg className="w-7 h-7 text-white ml-1" fill="currentColor" viewBox="0 0 20 20">
|
|
<path d="M6.3 4.1c-.4-.2-.8 0-.8.4v11c0 .4.4.6.8.4l9-5.5c.3-.2.3-.6 0-.8l-9-5.5z" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
{/* Privacy Badge */}
|
|
{!isPublic && (
|
|
<div className="absolute top-2 right-2 px-2 py-1 bg-zinc-900/80 backdrop-blur-sm rounded text-xs text-zinc-300 flex items-center gap-1">
|
|
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fillRule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" />
|
|
</svg>
|
|
Private
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Playlist Info */}
|
|
<div>
|
|
<h3 className="font-semibold text-white truncate mb-1 group-hover:text-purple-400 transition">
|
|
{title}
|
|
</h3>
|
|
|
|
{description && (
|
|
<p className="text-sm text-zinc-400 line-clamp-2 mb-1">
|
|
{description}
|
|
</p>
|
|
)}
|
|
|
|
<p className="text-xs text-zinc-500">
|
|
{songCount} {songCount === 1 ? 'song' : 'songs'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|