'use client'; import { useEffect, useState } from 'react'; import { useParams, useRouter } from 'next/navigation'; import WaveformEditor from '@/components/WaveformEditor'; interface Song { id: number; title: string; artist: string; filename: string; } interface SpecialSong { id: number; songId: number; startTime: number; order: number | null; song: Song; } interface Special { id: number; name: string; maxAttempts: number; unlockSteps: string; songs: SpecialSong[]; } export default function SpecialEditorPage() { const params = useParams(); const router = useRouter(); const specialId = params.id as string; const [special, setSpecial] = useState(null); const [selectedSongId, setSelectedSongId] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); useEffect(() => { fetchSpecial(); }, [specialId]); const fetchSpecial = async () => { try { const res = await fetch(`/api/specials/${specialId}`); if (res.ok) { const data = await res.json(); setSpecial(data); if (data.songs.length > 0) { setSelectedSongId(data.songs[0].songId); } } } catch (error) { console.error('Error fetching special:', error); } finally { setLoading(false); } }; const handleStartTimeChange = async (songId: number, newStartTime: number) => { if (!special) return; setSaving(true); try { const res = await fetch(`/api/specials/${specialId}/songs`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ songId, startTime: newStartTime }) }); if (res.ok) { // Update local state setSpecial(prev => { if (!prev) return prev; return { ...prev, songs: prev.songs.map(ss => ss.songId === songId ? { ...ss, startTime: newStartTime } : ss ) }; }); } } catch (error) { console.error('Error updating start time:', error); } finally { setSaving(false); } }; if (loading) { return (

Loading...

); } if (!special) { return (

Special not found

); } const selectedSpecialSong = special.songs.find(ss => ss.songId === selectedSongId); const unlockSteps = JSON.parse(special.unlockSteps); const totalDuration = unlockSteps[unlockSteps.length - 1]; return (

Edit Special: {special.name}

Max Attempts: {special.maxAttempts} | Puzzle Duration: {totalDuration}s

{special.songs.length === 0 ? (

No songs assigned to this special yet.

Go back to the admin dashboard to add songs to this special.

) : (

Select Song to Curate

{special.songs.map(ss => (
setSelectedSongId(ss.songId)} style={{ padding: '1rem', background: selectedSongId === ss.songId ? '#4f46e5' : '#f3f4f6', color: selectedSongId === ss.songId ? 'white' : 'black', borderRadius: '0.5rem', cursor: 'pointer', border: selectedSongId === ss.songId ? '2px solid #4f46e5' : '2px solid transparent' }} >
{ss.song.title}
{ss.song.artist}
Start: {ss.startTime}s
))}
{selectedSpecialSong && (

Curate: {selectedSpecialSong.song.title}

Click on the waveform to select where the puzzle should start. The highlighted region shows what players will hear.

handleStartTimeChange(selectedSpecialSong.songId, newStartTime)} /> {saving && (
Saving...
)}
)}
)}
); }