bookyard 0.1.1

Build and locally edit a bookshelf for multiple mdBook projects.
const configEl = document.querySelector("#config");
const booksEl = document.querySelector("#books");
const statusEl = document.querySelector("#status");

function setStatus(message) {
  statusEl.textContent = message;
}

function renderBooks(config) {
  booksEl.innerHTML = "";
  for (const book of config.books ?? []) {
    const row = document.createElement("div");
    row.className = "book-row";
    const title = document.createElement("strong");
    title.textContent = book.title;
    const meta = document.createElement("span");
    meta.textContent = `${book.id} ยท ${(book.folders ?? []).join(", ") || "Unsorted"}`;
    row.append(title, meta);
    booksEl.append(row);
  }
}

async function loadConfig() {
  const res = await fetch("/__bookyard/api/config");
  if (!res.ok) throw new Error(await res.text());
  const config = await res.json();
  configEl.value = JSON.stringify(config, null, 2);
  renderBooks(config);
  setStatus("Loaded");
}

async function saveConfig() {
  const config = JSON.parse(configEl.value);
  const res = await fetch("/__bookyard/api/config", {
    method: "PUT",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(config),
  });
  if (!res.ok) throw new Error(await res.text());
  renderBooks(await res.json());
  setStatus("Saved");
}

async function rebuild() {
  const res = await fetch("/__bookyard/api/build", { method: "POST" });
  if (!res.ok) throw new Error(await res.text());
  setStatus("Rebuilt");
}

document.querySelector("#reload").addEventListener("click", () => loadConfig().catch((err) => setStatus(err.message)));
document.querySelector("#save").addEventListener("click", () => saveConfig().catch((err) => setStatus(err.message)));
document.querySelector("#build").addEventListener("click", () => rebuild().catch((err) => setStatus(err.message)));

loadConfig().catch((err) => setStatus(err.message));