project-standalo-sonic-cloud/app/album/[id]/page.tsx

91 lines
2.7 KiB
TypeScript

import { AlbumHeader } from '@/components/AlbumHeader'
import { TrackList } from '@/components/TrackList'
interface PageProps {
params: Promise<{ id: string }>
}
async function getAlbum(id: string) {
const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/albums/${id}`, {
cache: 'no-store',
})
if (!res.ok) throw new Error('Album not found')
const data = await res.json()
return data.album
}
export default async function AlbumPage({ params }: PageProps) {
const { id } = await params
const album = await getAlbum(id)
// Calculate total duration from songs
const totalDuration = album.songs?.reduce((acc: number, song: any) => acc + (song.duration || 0), 0) || 0
// Transform songs for TrackList
const tracks = album.songs?.map((song: any, index: number) => ({
id: song.id,
title: song.title,
artistName: album.artist?.name || 'Unknown Artist',
duration: song.duration || 0,
plays: song.plays,
position: index + 1
})) || []
return (
<main className="min-h-screen bg-zinc-950">
<AlbumHeader
title={album.title}
artistName={album.artist?.name || 'Unknown Artist'}
artistId={album.artistId}
coverUrl={album.coverUrl}
releaseDate={album.releaseDate}
trackCount={album.songs?.length || 0}
duration={totalDuration}
type={album.type || 'album'}
/>
<div className="max-w-7xl mx-auto px-4 py-8">
{/* Track List */}
{tracks.length > 0 && (
<section className="mb-8">
<TrackList tracks={tracks} showPosition />
</section>
)}
{/* Album Info */}
<section className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-12 text-zinc-300">
<div>
<h3 className="text-lg font-semibold text-white mb-2">Release Date</h3>
<p>{new Date(album.releaseDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}</p>
</div>
{album.label && (
<div>
<h3 className="text-lg font-semibold text-white mb-2">Label</h3>
<p>{album.label.name}</p>
</div>
)}
{album.songs && album.songs.length > 0 && (
<div>
<h3 className="text-lg font-semibold text-white mb-2">Total Duration</h3>
<p>
{Math.floor(album.songs.reduce((acc: number, song: any) => acc + song.duration, 0) / 60)} minutes
</p>
</div>
)}
<div>
<h3 className="text-lg font-semibold text-white mb-2">Tracks</h3>
<p>{album.songs?.length || 0} songs</p>
</div>
</section>
</div>
</main>
)
}