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

115 lines
3.7 KiB
TypeScript

'use client'
import { UploadForm, UploadFormData } from '@/components/UploadForm'
import { WaveformDisplay } from '@/components/WaveformDisplay'
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
export default function UploadPage() {
const router = useRouter()
const [audioFile, setAudioFile] = useState<File | null>(null)
const [genres, setGenres] = useState<Array<{ id: string; name: string }>>([])
const [isLoading, setIsLoading] = useState(false)
useEffect(() => {
fetchGenres()
}, [])
const fetchGenres = async () => {
try {
const res = await fetch('/api/discover/genres')
if (res.ok) {
const data = await res.json()
setGenres(data.genres || [])
}
} catch (error) {
console.error('Failed to fetch genres:', error)
}
}
const handleSubmit = async (data: UploadFormData) => {
if (!data.audioFile) return
setAudioFile(data.audioFile)
setIsLoading(true)
try {
const formData = new FormData()
formData.append('audio', data.audioFile)
formData.append('title', data.title)
if (data.coverFile) formData.append('cover', data.coverFile)
if (data.albumId) formData.append('albumId', data.albumId)
if (data.genreIds.length > 0) formData.append('genreIds', JSON.stringify(data.genreIds))
if (data.releaseDate) formData.append('releaseDate', data.releaseDate)
const res = await fetch('/api/songs/upload', {
method: 'POST',
body: formData,
})
if (res.ok) {
const result = await res.json()
router.push(`/artist/${result.song?.artistId || ''}`)
}
} catch (error) {
console.error('Upload failed:', error)
} finally {
setIsLoading(false)
}
}
return (
<main className="min-h-screen bg-zinc-950">
<div className="max-w-4xl mx-auto px-4 py-8">
{/* Header */}
<div className="mb-8">
<h1 className="text-4xl font-bold text-white mb-4">Upload Music</h1>
<p className="text-xl text-zinc-400">
Share your music with the world
</p>
</div>
{/* Waveform Preview */}
{audioFile && (
<div className="mb-8 bg-zinc-900 rounded-lg p-6">
<h3 className="text-lg font-semibold text-white mb-4">Audio Preview</h3>
<WaveformDisplay audioFile={audioFile} />
</div>
)}
{/* Upload Form */}
<div className="bg-zinc-900 rounded-lg p-8">
<UploadForm
onSubmit={handleSubmit}
genres={genres}
isLoading={isLoading}
/>
</div>
{/* Guidelines */}
<div className="mt-8 p-6 bg-zinc-900/50 rounded-lg border border-zinc-800">
<h3 className="text-lg font-semibold text-white mb-4">Upload Guidelines</h3>
<ul className="space-y-2 text-zinc-400">
<li className="flex items-start gap-2">
<span className="text-purple-500 mt-1"></span>
<span>Audio files must be in MP3, WAV, or FLAC format</span>
</li>
<li className="flex items-start gap-2">
<span className="text-purple-500 mt-1"></span>
<span>Maximum file size: 100MB</span>
</li>
<li className="flex items-start gap-2">
<span className="text-purple-500 mt-1"></span>
<span>Make sure you own the rights to the music you upload</span>
</li>
<li className="flex items-start gap-2">
<span className="text-purple-500 mt-1"></span>
<span>Add accurate metadata for better discoverability</span>
</li>
</ul>
</div>
</div>
</main>
)
}