101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
'use client'
|
|
|
|
export interface AlbumHeaderProps {
|
|
title: string
|
|
artistName: string
|
|
artistId: string
|
|
coverUrl?: string
|
|
releaseDate: string
|
|
trackCount: number
|
|
duration: number
|
|
type?: 'album' | 'single' | 'ep'
|
|
onPlayAll?: () => void
|
|
onArtistClick?: () => void
|
|
}
|
|
|
|
export function AlbumHeader({
|
|
title,
|
|
artistName,
|
|
artistId,
|
|
coverUrl,
|
|
releaseDate,
|
|
trackCount,
|
|
duration,
|
|
type = 'album',
|
|
onPlayAll,
|
|
onArtistClick
|
|
}: AlbumHeaderProps) {
|
|
const formatDuration = (seconds: number) => {
|
|
const hours = Math.floor(seconds / 3600)
|
|
const minutes = Math.floor((seconds % 3600) / 60)
|
|
if (hours > 0) return `${hours} hr ${minutes} min`
|
|
return `${minutes} min`
|
|
}
|
|
|
|
const formatDate = (dateString: string) => {
|
|
const date = new Date(dateString)
|
|
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-end gap-8 mb-8 p-8 bg-gradient-to-b from-zinc-900/80 to-transparent">
|
|
{/* Cover Image */}
|
|
<div className="flex-shrink-0">
|
|
<div className="w-64 h-64 rounded-lg overflow-hidden bg-zinc-800 shadow-2xl">
|
|
{coverUrl ? (
|
|
<img
|
|
src={coverUrl}
|
|
alt={title}
|
|
className="w-full h-full object-cover"
|
|
/>
|
|
) : (
|
|
<div className="w-full h-full flex items-center justify-center">
|
|
<svg className="w-32 h-32 text-zinc-600" fill="currentColor" viewBox="0 0 20 20">
|
|
<path d="M18 3a1 1 0 00-1.196-.98l-10 2A1 1 0 006 5v9.114A4.369 4.369 0 005 14c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V7.82l8-1.6v5.894A4.37 4.37 0 0015 12c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V3z" />
|
|
</svg>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Album Info */}
|
|
<div className="flex-1 pb-4">
|
|
<p className="text-sm font-semibold text-zinc-400 uppercase mb-2">
|
|
{type}
|
|
</p>
|
|
|
|
<h1 className="text-6xl font-bold text-white mb-4 line-clamp-2">
|
|
{title}
|
|
</h1>
|
|
|
|
<div className="flex items-center gap-2 text-sm text-zinc-300 mb-6">
|
|
<button
|
|
onClick={onArtistClick}
|
|
className="font-semibold hover:underline"
|
|
>
|
|
{artistName}
|
|
</button>
|
|
<span>•</span>
|
|
<span>{formatDate(releaseDate)}</span>
|
|
<span>•</span>
|
|
<span>{trackCount} {trackCount === 1 ? 'song' : 'songs'}</span>
|
|
<span>•</span>
|
|
<span>{formatDuration(duration)}</span>
|
|
</div>
|
|
|
|
{/* Play Button */}
|
|
{onPlayAll && (
|
|
<button
|
|
onClick={onPlayAll}
|
|
className="w-14 h-14 rounded-full bg-purple-500 hover:bg-purple-600 hover:scale-105 flex items-center justify-center transition-all shadow-lg"
|
|
>
|
|
<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>
|
|
</div>
|
|
)
|
|
}
|