"use client" import { useEffect, useState, useCallback } 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, UserCircle, Plus } 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 Musician { id: number name: string slug: string bio: string | null image_url: string | null primary_instrument: string | null } export default function AdminMusiciansPage() { const { user, token } = useAuth() const router = useRouter() const [musicians, setMusicians] = useState([]) const [loading, setLoading] = useState(true) const [search, setSearch] = useState("") const [editingMusician, setEditingMusician] = useState(null) const [isCreating, setIsCreating] = useState(false) const [newMusician, setNewMusician] = useState({ name: "", bio: "", image_url: "", primary_instrument: "" }) const [saving, setSaving] = useState(false) const fetchMusicians = useCallback(async () => { if (!token) return try { const res = await fetch(`${getApiUrl()}/musicians?limit=100`, { headers: { Authorization: `Bearer ${token}` } }) if (res.ok) setMusicians(await res.json()) } catch (e) { console.error("Failed to fetch musicians", e) } finally { setLoading(false) } }, [token]) useEffect(() => { if (!user) { router.push("/login") return } if (user.role !== "admin") { router.push("/") return } fetchMusicians() }, [user, router, fetchMusicians]) const createMusician = async () => { if (!token || !newMusician.name) return setSaving(true) try { const res = await fetch(`${getApiUrl()}/musicians`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify(newMusician) }) if (res.ok) { fetchMusicians() setIsCreating(false) setNewMusician({ name: "", bio: "", image_url: "", primary_instrument: "" }) } } catch (e) { console.error("Failed to create musician", e) } finally { setSaving(false) } } const filteredMusicians = musicians.filter(m => m.name.toLowerCase().includes(search.toLowerCase()) || m.primary_instrument?.toLowerCase().includes(search.toLowerCase()) ) if (loading) { return (
{[1, 2, 3].map(i =>
)}
) } return (

Musician Management

setSearch(e.target.value)} className="pl-9" />
{filteredMusicians.map(musician => ( ))}
Musician Instrument Bio Actions
{musician.name} {musician.primary_instrument || "—"} {musician.bio ? ( Has Bio ) : ( No Bio )}
{filteredMusicians.length === 0 && (
No musicians found. Add some to get started!
)}
{/* Create Dialog */} Add New Musician
setNewMusician({ ...newMusician, name: e.target.value })} />
setNewMusician({ ...newMusician, primary_instrument: e.target.value })} />