feat: add request form and live queue UI
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
import { Queue } from "./queue";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return <main>Lyra</main>;
|
return (
|
||||||
|
<main>
|
||||||
|
<h1>Lyra</h1>
|
||||||
|
<Queue />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
type Row = {
|
||||||
|
id: string;
|
||||||
|
artist: string;
|
||||||
|
album: string;
|
||||||
|
status: string;
|
||||||
|
job: { state: string; currentStage: string } | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Queue() {
|
||||||
|
const [rows, setRows] = useState<Row[]>([]);
|
||||||
|
const [artist, setArtist] = useState("");
|
||||||
|
const [album, setAlbum] = useState("");
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
const res = await fetch("/api/requests");
|
||||||
|
const body = await res.json();
|
||||||
|
setRows(body.requests);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
refresh();
|
||||||
|
const id = setInterval(refresh, 2000);
|
||||||
|
return () => clearInterval(id);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function submit(e: React.FormEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!artist.trim() || !album.trim()) return;
|
||||||
|
await fetch("/api/requests", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({ artist, album }),
|
||||||
|
});
|
||||||
|
setArtist("");
|
||||||
|
setAlbum("");
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<form onSubmit={submit}>
|
||||||
|
<input aria-label="artist" placeholder="Artist" value={artist} onChange={(e) => setArtist(e.target.value)} />
|
||||||
|
<input aria-label="album" placeholder="Album" value={album} onChange={(e) => setAlbum(e.target.value)} />
|
||||||
|
<button type="submit">Request</button>
|
||||||
|
</form>
|
||||||
|
<ul>
|
||||||
|
{rows.map((r) => (
|
||||||
|
<li key={r.id}>
|
||||||
|
{r.artist} — {r.album} · <strong>{r.job?.state ?? r.status}</strong>
|
||||||
|
{r.job ? ` (${r.job.currentStage})` : ""}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user