project-standalo-sonic-cloud/app/playlists/page.tsx

118 lines
3.7 KiB
TypeScript

'use client'
import { PlaylistCard } from '@/components/PlaylistCard'
import { CreatePlaylistModal, CreatePlaylistData } from '@/components/CreatePlaylistModal'
import { useState, useEffect } from 'react'
export default function PlaylistsPage() {
const [playlists, setPlaylists] = useState<any[]>([])
const [isModalOpen, setIsModalOpen] = useState(false)
const [isCreating, setIsCreating] = useState(false)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchPlaylists()
}, [])
const fetchPlaylists = async () => {
try {
const res = await fetch('/api/playlists')
if (res.ok) {
const data = await res.json()
setPlaylists(data.playlists || [])
}
} catch (error) {
console.error('Failed to fetch playlists:', error)
} finally {
setLoading(false)
}
}
const handleCreatePlaylist = async (data: CreatePlaylistData) => {
setIsCreating(true)
try {
const res = await fetch('/api/playlists', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: data.title,
description: data.description,
isPublic: data.isPublic,
}),
})
if (res.ok) {
const result = await res.json()
setPlaylists([result.playlist, ...playlists])
setIsModalOpen(false)
}
} catch (error) {
console.error('Failed to create playlist:', error)
} finally {
setIsCreating(false)
}
}
return (
<main className="min-h-screen bg-zinc-950">
<div className="max-w-7xl mx-auto px-4 py-8">
{/* Header */}
<div className="flex items-center justify-between mb-8">
<div>
<h1 className="text-4xl font-bold text-white mb-4">My Playlists</h1>
<p className="text-xl text-zinc-400">
Create and manage your music collections
</p>
</div>
<button
onClick={() => setIsModalOpen(true)}
className="px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-white font-semibold rounded-lg transition-colors"
>
Create Playlist
</button>
</div>
{/* Playlists Grid */}
{loading ? (
<div className="text-center py-16">
<p className="text-zinc-400">Loading playlists...</p>
</div>
) : playlists.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
{playlists.map((playlist) => (
<PlaylistCard
key={playlist.id}
id={playlist.id}
title={playlist.name}
description={playlist.description}
coverUrl={playlist.coverUrl}
songCount={playlist.songs?.length || playlist._count?.songs || 0}
isPublic={playlist.isPublic}
/>
))}
</div>
) : (
<div className="text-center py-16">
<p className="text-xl text-zinc-400 mb-4">You don't have any playlists yet</p>
<p className="text-zinc-500 mb-6">Create your first playlist to start organizing your music</p>
<button
onClick={() => setIsModalOpen(true)}
className="px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-white font-semibold rounded-lg transition-colors"
>
Create Your First Playlist
</button>
</div>
)}
</div>
{/* Create Playlist Modal */}
<CreatePlaylistModal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
onSubmit={handleCreatePlaylist}
isLoading={isCreating}
/>
</main>
)
}