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}
)}