115 lines
3.7 KiB
TypeScript
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>
|
|
)
|
|
}
|