From fb833a7976b48f4ed8e7bd35a30c74224f04529b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=B6rdle=20Bot?= Date: Sun, 7 Dec 2025 10:07:43 +0100 Subject: [PATCH] =?UTF-8?q?Fix:=20Waveform=20Editor=20l=C3=A4dt=20nicht=20?= =?UTF-8?q?f=C3=BCr=20Titel=20ohne=20vollst=C3=A4ndige=20Song-Daten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Filtere Songs ohne vollständige Song-Daten (song, filename) in CurateSpecialEditor - Füge defensive Prüfungen hinzu bevor WaveformEditor gerendert wird - Filtere unvollständige Songs bereits auf API-Ebene in curator/specials/[id] - Verhindert Fehler wenn Songs ohne filename oder song-Objekt geladen werden --- app/api/curator/specials/[id]/route.ts | 9 ++++++++- components/CurateSpecialEditor.tsx | 23 ++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/api/curator/specials/[id]/route.ts b/app/api/curator/specials/[id]/route.ts index a4c7a90..da6e1e9 100644 --- a/app/api/curator/specials/[id]/route.ts +++ b/app/api/curator/specials/[id]/route.ts @@ -52,7 +52,14 @@ export async function GET( return NextResponse.json({ error: 'Special not found' }, { status: 404 }); } - return NextResponse.json(special); + // Filtere Songs ohne vollständige Song-Daten (song, song.filename) + // Dies verhindert Fehler im Frontend, wenn Songs gelöscht wurden oder Daten fehlen + const filteredSongs = special.songs.filter(ss => ss.song && ss.song.filename); + + return NextResponse.json({ + ...special, + songs: filteredSongs, + }); } diff --git a/components/CurateSpecialEditor.tsx b/components/CurateSpecialEditor.tsx index 5bdf3a5..1f5a8d7 100644 --- a/components/CurateSpecialEditor.tsx +++ b/components/CurateSpecialEditor.tsx @@ -62,11 +62,14 @@ export default function CurateSpecialEditor({ saveChangesLabel = '💾 Save Changes', savedLabel = '✓ Saved', }: CurateSpecialEditorProps) { + // Filtere Songs ohne vollständige Song-Daten (song, song.filename) + const validSongs = special.songs.filter(ss => ss.song && ss.song.filename); + const [selectedSongId, setSelectedSongId] = useState( - special.songs.length > 0 ? special.songs[0].songId : null + validSongs.length > 0 ? validSongs[0].songId : null ); const [pendingStartTime, setPendingStartTime] = useState( - special.songs.length > 0 ? special.songs[0].startTime : null + validSongs.length > 0 ? validSongs[0].startTime : null ); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); const [saving, setSaving] = useState(false); @@ -77,7 +80,7 @@ export default function CurateSpecialEditor({ const unlockSteps = JSON.parse(special.unlockSteps); const totalDuration = unlockSteps[unlockSteps.length - 1]; - const selectedSpecialSong = special.songs.find(ss => ss.songId === selectedSongId) ?? null; + const selectedSpecialSong = validSongs.find(ss => ss.songId === selectedSongId) ?? null; const handleStartTimeChange = (newStartTime: number) => { setPendingStartTime(newStartTime); @@ -111,7 +114,7 @@ export default function CurateSpecialEditor({

- {special.songs.length === 0 ? ( + {validSongs.length === 0 ? (

{noSongsHint}

@@ -125,7 +128,7 @@ export default function CurateSpecialEditor({ Select Song to Curate

- {special.songs.map(ss => ( + {validSongs.map(ss => (
{ @@ -152,7 +155,7 @@ export default function CurateSpecialEditor({
- {selectedSpecialSong && ( + {selectedSpecialSong && selectedSpecialSong.song && selectedSpecialSong.song.filename ? (

Curate: {selectedSpecialSong.song.title} @@ -189,7 +192,13 @@ export default function CurateSpecialEditor({ />

- )} + ) : selectedSpecialSong ? ( +
+

+ Fehler: Song-Daten unvollständig. Bitte wählen Sie einen anderen Song. +

+
+ ) : null} )}