This commit is contained in:
2026-05-09 14:51:25 -04:00
parent 97fabc2c17
commit f23a8a2be6
20 changed files with 382 additions and 185 deletions

View File

@@ -1,6 +1,37 @@
import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { api, Library } from "../api/client";
import { api, type Library } from "../api/client";
function LibraryRow({ lib, onRemove }: { lib: Library; onRemove: (id: number) => void }) {
const { data } = useQuery({
queryKey: ["scan-status", lib.id],
queryFn: () => api.libraries.scanStatus(lib.id),
refetchInterval: (query) => (query.state.data?.scanning ? 2000 : false),
});
const scanning = data?.scanning ?? false;
return (
<li style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 0", borderBottom: "1px solid var(--border-subtle)" }}>
<div>
<strong style={{ color: "var(--text)" }}>{lib.name}</strong>
{scanning && (
<span style={{ marginLeft: 8, fontSize: 12, color: "var(--accent)" }}>
Scanning
</span>
)}
<div style={{ fontSize: 12, color: "var(--text-secondary)" }}>{lib.path}</div>
</div>
<button
onClick={() => onRemove(lib.id)}
disabled={scanning}
style={{ color: scanning ? "var(--text-muted)" : "var(--danger)", background: "transparent", border: "none" }}
>
Remove
</button>
</li>
);
}
export default function SettingsPage() {
const qc = useQueryClient();
@@ -31,49 +62,24 @@ export default function SettingsPage() {
return (
<div style={{ padding: "2rem", maxWidth: 600 }}>
<h1>Settings</h1>
<h2>Libraries</h2>
<h1 style={{ color: "var(--text)" }}>Settings</h1>
<h2 style={{ color: "var(--text)" }}>Libraries</h2>
<form
onSubmit={(e) => { e.preventDefault(); addMutation.mutate(); }}
style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 24 }}
>
<input
placeholder="Library name"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
<input
placeholder="/path/to/directory"
value={path}
onChange={(e) => setPath(e.target.value)}
required
/>
{error && <p style={{ color: "red", margin: 0 }}>{error}</p>}
<button type="submit" disabled={addMutation.isPending}>
<input placeholder="Library name" value={name} onChange={(e) => setName(e.target.value)} required />
<input placeholder="/path/to/directory" value={path} onChange={(e) => setPath(e.target.value)} required />
{error && <p style={{ color: "var(--danger)", margin: 0 }}>{error}</p>}
<button type="submit" disabled={addMutation.isPending} style={{ background: "var(--accent)", color: "#fff", border: "none" }}>
{addMutation.isPending ? "Adding…" : "Add Library"}
</button>
</form>
<ul style={{ listStyle: "none", padding: 0 }}>
{libraries.map((lib) => (
<li
key={lib.id}
style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 0", borderBottom: "1px solid #eee" }}
>
<div>
<strong>{lib.name}</strong>
<div style={{ fontSize: 12, color: "#666" }}>{lib.path}</div>
</div>
<button
onClick={() => deleteMutation.mutate(lib.id)}
disabled={deleteMutation.isPending}
style={{ color: "red" }}
>
Remove
</button>
</li>
<LibraryRow key={lib.id} lib={lib} onRemove={(id) => deleteMutation.mutate(id)} />
))}
</ul>
</div>