feat(web): restyle Artists, Discover, Wanted, discography + preview (Phase 2)
Convert the remaining pages onto the Pressing Plant system: PageHead component, shared list-row / toggle / small+ghost button / tracklist classes, and page wrappers trimmed now that the shell provides masthead + nav. All logic and test hooks (aria-labels, button text) preserved. Verified in the real app across both themes (Playwright): artists/discover/wanted/discography render cohesively with real data. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { PageHead } from "../_ui/page-head";
|
||||
import { SectionHeader } from "../_ui/section-header";
|
||||
|
||||
type Wanted = {
|
||||
id: string;
|
||||
@@ -11,6 +13,11 @@ type Wanted = {
|
||||
lastSearchedAt: 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<Wanted[]>([]);
|
||||
const [artist, setArtist] = useState("");
|
||||
@@ -35,7 +42,7 @@ export function WantedClient() {
|
||||
body: JSON.stringify({ artist, album }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
setError((await res.json()).error ?? "failed to add");
|
||||
setError((await res.json()).error ?? "Couldn’t add that — no MusicBrainz match?");
|
||||
return;
|
||||
}
|
||||
setArtist("");
|
||||
@@ -50,21 +57,48 @@ export function WantedClient() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={add}>
|
||||
<input aria-label="wanted artist" placeholder="Artist" value={artist} onChange={(e) => setArtist(e.target.value)} />
|
||||
<input aria-label="wanted album" placeholder="Album" value={album} onChange={(e) => setAlbum(e.target.value)} />
|
||||
<button type="submit">Add to wanted</button>
|
||||
{error ? <span> {error}</span> : null}
|
||||
<PageHead title="Wanted" eyebrow="Cutting list · acquire & upgrade" />
|
||||
|
||||
<form className="request-form" onSubmit={add}>
|
||||
<label className="field">
|
||||
<span>Artist</span>
|
||||
<input aria-label="wanted artist" placeholder="Artist" value={artist} onChange={(e) => setArtist(e.target.value)} />
|
||||
</label>
|
||||
<label className="field">
|
||||
<span>Album</span>
|
||||
<input aria-label="wanted album" placeholder="Album" value={album} onChange={(e) => setAlbum(e.target.value)} />
|
||||
</label>
|
||||
<button type="submit" className="btn accent">
|
||||
Add to wanted
|
||||
</button>
|
||||
{error ? <span className="notice">{error}</span> : null}
|
||||
</form>
|
||||
<ul>
|
||||
{rows.map((w) => (
|
||||
<li key={w.id}>
|
||||
{w.artistName} — {w.album} · <em>{w.currentQualityClass !== null ? `have q${w.currentQualityClass}, upgrading` : w.state}</em>
|
||||
{w.lastSearchedAt ? ` · last tried ${new Date(w.lastSearchedAt).toLocaleString()}` : " · never tried"}{" "}
|
||||
<button onClick={() => searchNow(w)}>Search now</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<SectionHeader title="Wanted" note={`${rows.length} on the list`} />
|
||||
{rows.length === 0 ? (
|
||||
<p className="empty">Nothing wanted yet. Add a release above, or send one over from an artist’s discography.</p>
|
||||
) : (
|
||||
<ul className="list">
|
||||
{rows.map((w) => (
|
||||
<li key={w.id} className="list-row">
|
||||
<div className="main">
|
||||
<div className="rtitle">
|
||||
{w.album} <span className="artist">· {w.artistName}</span>
|
||||
</div>
|
||||
<div className="rmeta">
|
||||
<span>{w.lastSearchedAt ? `last tried ${new Date(w.lastSearchedAt).toLocaleDateString()}` : "never tried"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="actions">
|
||||
<span className="chip">{stateLabel(w)}</span>
|
||||
<button className="btn sm ghost" onClick={() => searchNow(w)}>
|
||||
Search now
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user