299 lines
12 KiB
HTML
299 lines
12 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>wordarr</title>
|
||
<link
|
||
rel="icon"
|
||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📚</text></svg>" />
|
||
<link rel="stylesheet" href="/style.css" />
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<h1>📚 wordarr</h1>
|
||
<nav>
|
||
<button data-view="search" class="active">Suche</button>
|
||
<button data-view="missing">
|
||
Missing <span id="missing-badge" class="badge" hidden></span>
|
||
</button>
|
||
<button data-view="imported">Importiert</button>
|
||
<button data-view="import">Import</button>
|
||
<button data-view="settings">Libraries</button>
|
||
</nav>
|
||
</header>
|
||
<main>
|
||
<section id="view-search">
|
||
<form id="search-form" class="bar">
|
||
<select id="search-type">
|
||
<option value="ebook">Ebook</option>
|
||
<option value="audiobook">Audiobook</option>
|
||
<option value="comic">Comic/Manga</option>
|
||
</select>
|
||
<input id="search-q" placeholder="Titel, Autor oder ISBN…" required />
|
||
<button type="submit" id="search-btn">Suchen</button>
|
||
<button type="button" id="manual-btn" class="secondary">
|
||
Manuell anlegen
|
||
</button>
|
||
</form>
|
||
<div id="search-results" class="cards"></div>
|
||
|
||
<dialog id="manual-dialog">
|
||
<form id="manual-form" method="dialog">
|
||
<h3>Manuell anfragen</h3>
|
||
<label
|
||
>Typ
|
||
<select name="media_type">
|
||
<option value="ebook">Ebook</option>
|
||
<option value="audiobook">Audiobook</option>
|
||
<option value="comic">Comic/Manga</option>
|
||
</select>
|
||
</label>
|
||
<label>Titel <input name="title" required /></label>
|
||
<label>Autor(en) <input name="authors" /></label>
|
||
<label>Sprecher <input name="narrator" /></label>
|
||
<label>Serie <input name="series" /></label>
|
||
<label>Band <input name="volume" type="number" min="0" /></label>
|
||
<label
|
||
>bis Band (Bulk, optional)
|
||
<input name="volume_to" type="number" min="0" />
|
||
<span class="muted"
|
||
>Legt pro Band/Folge eine Anfrage an, z.B. 1 bis 300</span
|
||
>
|
||
</label>
|
||
<label>Jahr <input name="year" type="number" /></label>
|
||
<label>ISBN/ID <input name="external_id" /></label>
|
||
<label
|
||
>Library
|
||
<select name="library_id" id="manual-library"></select
|
||
></label>
|
||
<div class="row">
|
||
<button value="cancel" class="secondary">Abbrechen</button>
|
||
<button value="ok" id="manual-submit">Anfragen</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<dialog id="series-dialog">
|
||
<h3 id="series-title">Serie anfragen</h3>
|
||
<p class="muted" id="series-info"></p>
|
||
<div class="bar wrap">
|
||
<label>von Folge <input id="series-from" type="number" min="0" /></label>
|
||
<label>bis Folge <input id="series-to" type="number" min="0" /></label>
|
||
<button type="button" id="series-all" class="secondary">Alle</button>
|
||
<button type="button" id="series-none" class="secondary">Keine</button>
|
||
</div>
|
||
<div id="series-list" class="series-list"></div>
|
||
<div class="row">
|
||
<label>Library <select id="series-library"></select></label>
|
||
</div>
|
||
<div class="row">
|
||
<button type="button" id="series-cancel" class="secondary">Abbrechen</button>
|
||
<button type="button" id="series-submit">Anfragen</button>
|
||
</div>
|
||
</dialog>
|
||
</section>
|
||
|
||
<section id="view-missing" hidden>
|
||
<div class="bar wrap">
|
||
<select id="missing-filter-type">
|
||
<option value="">Alle Typen</option>
|
||
<option value="ebook">Ebook</option>
|
||
<option value="audiobook">Audiobook</option>
|
||
<option value="comic">Comic/Manga</option>
|
||
</select>
|
||
<select id="missing-filter-library">
|
||
<option value="">Alle Libraries</option>
|
||
</select>
|
||
<input id="missing-search" placeholder="Filtern (Titel/Autor/Serie)…" />
|
||
<button id="missing-select-all" class="secondary">Alle auswählen</button>
|
||
<button id="missing-bulk-delete" class="danger" hidden>
|
||
Ausgewählte entfernen
|
||
</button>
|
||
<div class="view-toggle" role="group" aria-label="Ansicht">
|
||
<button data-viewmode="list" title="Liste">☰</button>
|
||
<button data-viewmode="small" title="Kleine Symbole">▦</button>
|
||
<button data-viewmode="large" title="Große Symbole">⊞</button>
|
||
</div>
|
||
</div>
|
||
<div id="missing-list" class="cards"></div>
|
||
</section>
|
||
|
||
<section id="view-imported" hidden>
|
||
<div class="bar wrap">
|
||
<input id="imported-search" placeholder="Filtern (Titel/Autor/Serie)…" />
|
||
<button id="imported-select-all" class="secondary">Alle auswählen</button>
|
||
<button id="imported-bulk-delete" class="danger" hidden>
|
||
Ausgewählte entfernen
|
||
</button>
|
||
<div class="view-toggle" role="group" aria-label="Ansicht">
|
||
<button data-viewmode="list" title="Liste">☰</button>
|
||
<button data-viewmode="small" title="Kleine Symbole">▦</button>
|
||
<button data-viewmode="large" title="Große Symbole">⊞</button>
|
||
</div>
|
||
</div>
|
||
<div id="imported-list" class="cards"></div>
|
||
</section>
|
||
|
||
<section id="view-import" hidden>
|
||
<div class="bar wrap">
|
||
<button id="scan-btn">Download-Ordner scannen</button>
|
||
<label class="muted"
|
||
><input type="checkbox" id="split-dirs" /> Ordner als Einzeldateien
|
||
behandeln (z.B. Folgen-Sammlungen)</label
|
||
>
|
||
<span id="scan-info" class="muted"></span>
|
||
</div>
|
||
<div class="bar wrap" id="import-toolbar" hidden>
|
||
<input id="import-filter-text" placeholder="Filtern (Name/Pfad)…" />
|
||
<select id="import-filter-mode">
|
||
<option value="all">Alle</option>
|
||
<option value="suggested">Nur mit Vorschlag</option>
|
||
<option value="unassigned">Nur ohne Zuordnung</option>
|
||
</select>
|
||
<select id="import-sort">
|
||
<option value="none">Reihenfolge: Scan</option>
|
||
<option value="score">Score absteigend</option>
|
||
<option value="name">Name A–Z</option>
|
||
</select>
|
||
<button id="import-select-suggested" class="secondary">
|
||
Alle mit Vorschlag auswählen
|
||
</button>
|
||
<button id="import-deselect-all" class="secondary">
|
||
Alle abwählen
|
||
</button>
|
||
</div>
|
||
<div class="table-scroll">
|
||
<table id="import-table" hidden>
|
||
<thead>
|
||
<tr>
|
||
<th></th>
|
||
<th>Datei/Ordner</th>
|
||
<th>Typ</th>
|
||
<th>Zuordnung</th>
|
||
<th>Score</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
<div class="bar" id="import-pager" hidden>
|
||
<button id="import-prev" class="secondary">← Zurück</button>
|
||
<span id="import-page-info" class="muted"></span>
|
||
<button id="import-next" class="secondary">Weiter →</button>
|
||
</div>
|
||
<div class="bar">
|
||
<button id="import-btn" hidden>Ausgewählte importieren</button>
|
||
</div>
|
||
<div id="import-summary"></div>
|
||
<div id="import-results"></div>
|
||
|
||
<dialog id="quick-dialog">
|
||
<h3>Suchen & Anfragen</h3>
|
||
<p class="muted mono" id="quick-file"></p>
|
||
<form id="quick-search-form" class="bar">
|
||
<input id="quick-q" placeholder="Titel/Serie suchen…" required />
|
||
<button type="submit">Suchen</button>
|
||
</form>
|
||
<label class="muted"
|
||
>Ziel-Library <select id="quick-library"></select
|
||
></label>
|
||
<div id="quick-open-requests"></div>
|
||
<div id="quick-results" class="cards"></div>
|
||
<div class="row">
|
||
<button type="button" id="quick-close" class="secondary">
|
||
Schließen
|
||
</button>
|
||
</div>
|
||
</dialog>
|
||
</section>
|
||
|
||
<section id="view-settings" hidden>
|
||
<h3>Libraries</h3>
|
||
<div class="table-scroll">
|
||
<table id="lib-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Name</th>
|
||
<th>Typ</th>
|
||
<th>Pfad</th>
|
||
<th>Ordner-Schema</th>
|
||
<th>Datei-Schema</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
<h4 id="lib-form-title">Neue Library</h4>
|
||
<form id="lib-form" class="bar wrap">
|
||
<input name="name" placeholder="Name (z.B. Kids)" required />
|
||
<select name="media_type">
|
||
<option value="ebook">Ebook</option>
|
||
<option value="audiobook">Audiobook</option>
|
||
<option value="comic">Comic/Manga</option>
|
||
</select>
|
||
<input
|
||
name="root_path"
|
||
placeholder="/ebooks/kids"
|
||
required
|
||
class="wide"
|
||
list="path-suggestions"
|
||
autocomplete="off" />
|
||
<datalist id="path-suggestions"></datalist>
|
||
<input
|
||
name="folder_template"
|
||
placeholder="Ordner-Schema (optional)"
|
||
class="wide" />
|
||
<input
|
||
name="file_template"
|
||
placeholder="Datei-Schema (optional)"
|
||
class="wide" />
|
||
<button type="submit" id="lib-form-submit">Anlegen</button>
|
||
<button type="button" id="lib-form-cancel" class="secondary" hidden>
|
||
Abbrechen
|
||
</button>
|
||
</form>
|
||
<p class="muted">
|
||
Platzhalter: {Author} {Authors} {Narrator} {Title} {Year} {Series}
|
||
{Volume}
|
||
</p>
|
||
</section>
|
||
</main>
|
||
|
||
<dialog id="detail-dialog">
|
||
<form id="detail-form" method="dialog">
|
||
<div class="detail-head">
|
||
<img id="detail-cover" alt="" hidden />
|
||
<div class="nocover" id="detail-nocover">?</div>
|
||
<div>
|
||
<h3 id="detail-title"></h3>
|
||
<p class="muted" id="detail-status"></p>
|
||
</div>
|
||
</div>
|
||
<label>Titel <input name="title" required /></label>
|
||
<label>Autor(en) <input name="authors" /></label>
|
||
<label>Sprecher <input name="narrator" /></label>
|
||
<label>Serie <input name="series" /></label>
|
||
<div class="row">
|
||
<label>Band <input name="volume" type="number" min="0" /></label>
|
||
<label>Jahr <input name="year" type="number" /></label>
|
||
</div>
|
||
<label>ISBN/ASIN <input name="external_id" /></label>
|
||
<label>Library <select name="library_id" id="detail-library"></select></label>
|
||
<p class="muted mono" id="detail-path"></p>
|
||
<div class="row">
|
||
<button value="cancel" class="secondary">Abbrechen</button>
|
||
<button type="button" id="detail-retag" class="secondary" hidden>
|
||
Speichern & neu taggen
|
||
</button>
|
||
<button value="ok" id="detail-save">Speichern</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<div id="toast" hidden></div>
|
||
<script src="/app.js"></script>
|
||
</body>
|
||
</html>
|