"use client"; import { useEffect, useState } from "react"; import { PageHead } from "../_ui/page-head"; import { SectionHeader } from "../_ui/section-header"; import { CoverArt } from "../_ui/cover-art"; import { AlbumModal } from "../_ui/album-modal"; import { toast } from "../_ui/toast"; type Wanted = { id: string; artistName: string; artistMbid: string | null; album: string; state: string; currentQualityClass: number | null; lastSearchedAt: string | null; rgMbid: string | null; primaryType: string | null; firstReleaseDate: string | null; }; function stateLabel(w: Wanted): string { if (w.currentQualityClass !== null) return `Have q${w.currentQualityClass} · upgrading`; return w.state === "wanted" ? "Wanted" : w.state; } export function WantedClient() { const [rows, setRows] = useState([]); const [artist, setArtist] = useState(""); const [album, setAlbum] = useState(""); const [error, setError] = useState(""); const [open, setOpen] = useState(null); async function refresh() { const res = await fetch("/api/wanted"); setRows((await res.json()).wanted); } useEffect(() => { refresh(); }, []); async function add(e: React.FormEvent) { e.preventDefault(); setError(""); if (!artist.trim() || !album.trim()) return; const res = await fetch("/api/wanted", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ artist, album }), }); if (!res.ok) { setError((await res.json()).error ?? "Couldn’t add that — no MusicBrainz match?"); return; } toast("Added to wanted"); setArtist(""); setAlbum(""); refresh(); } async function searchNow(w: Wanted) { await fetch(`/api/releases/${w.id}/search`, { method: "POST" }); toast(`Searching for ${w.album}`); refresh(); } return (
{error ? {error} : null}
{rows.length === 0 ? (

Nothing wanted yet. Add a release above, or send one over from an artist’s discography.

) : (
    {rows.map((w) => (
  • {stateLabel(w)}
  • ))}
)} {open ? ( setOpen(null)} album={{ rgMbid: open.rgMbid, album: open.album, artist: open.artistName, year: open.firstReleaseDate?.slice(0, 4) ?? null, type: open.primaryType, artistMbid: open.artistMbid, }} status={{stateLabel(open)}} actions={ } /> ) : null}
); }