"use client" import { useEffect, useState } from "react" import { useAuth } from "@/contexts/auth-context" import { useRouter } from "next/navigation" import { Card, CardContent } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Badge } from "@/components/ui/badge" import { Search, Edit, Save, X, Music2 } from "lucide-react" import { getApiUrl } from "@/lib/api-config" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog" import { Label } from "@/components/ui/label" import Link from "next/link" interface Song { id: number title: string slug: string original_artist: string | null artist_id: number | null notes: string | null youtube_link: string | null } export default function AdminSongsPage() { const { user, token } = useAuth() const router = useRouter() const [songs, setSongs] = useState([]) const [loading, setLoading] = useState(true) const [search, setSearch] = useState("") const [editingSong, setEditingSong] = useState(null) const [saving, setSaving] = useState(false) useEffect(() => { if (!user) { router.push("/login") return } if (user.role !== "admin") { router.push("/") return } fetchSongs() }, [user, router]) const fetchSongs = async () => { if (!token) return try { const res = await fetch(`${getApiUrl()}/songs?limit=200`, { headers: { Authorization: `Bearer ${token}` } }) if (res.ok) { const data = await res.json() setSongs(data.songs || data) } } catch (e) { console.error("Failed to fetch songs", e) } finally { setLoading(false) } } const updateSong = async () => { if (!token || !editingSong) return setSaving(true) try { const res = await fetch(`${getApiUrl()}/admin/songs/${editingSong.id}`, { method: "PATCH", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ notes: editingSong.notes, youtube_link: editingSong.youtube_link, original_artist: editingSong.original_artist }) }) if (res.ok) { fetchSongs() setEditingSong(null) } } catch (e) { console.error("Failed to update song", e) } finally { setSaving(false) } } const filteredSongs = songs.filter(s => s.title.toLowerCase().includes(search.toLowerCase()) || s.original_artist?.toLowerCase().includes(search.toLowerCase()) ) if (loading) { return (
{[1, 2, 3].map(i =>
)}
) } return (

Song Management

setSearch(e.target.value)} className="pl-9" />
{filteredSongs.slice(0, 100).map(song => ( ))}
Title Original Artist Type Actions
{song.title} {song.original_artist || "—"} {song.original_artist && song.original_artist !== "Goose" ? ( Cover ) : ( Original )}
{filteredSongs.length === 0 && (
No songs found
)}
setEditingSong(null)}> Edit Song: {editingSong?.title} {editingSong && (
setEditingSong({ ...editingSong, original_artist: e.target.value })} />