mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-09-24 22:05:20 +01:00
UI Overhaul - Tailwind CSS (#259)
New Homepage <img width="2559" height="1388" alt="image" src="https://github.com/user-attachments/assets/787668c6-61a9-4a2d-9878-9daaee8ae114" /> New Card Layout: <img width="2547" height="1250" alt="image" src="https://github.com/user-attachments/assets/44d015f9-c29d-4cac-a8b4-1c4ff7d40009" /> Light-Mode: <img width="2547" height="1253" alt="image" src="https://github.com/user-attachments/assets/7f81f6d7-ec69-4680-8ddc-4737601d00bb" /> New Download Queue and Status: <img width="1260" height="146" alt="image" src="https://github.com/user-attachments/assets/4acbb5a3-e985-4b23-8527-392e21151fa4" /> Haven't contributed to open-source before, but figured I could try and help out on the UI side of the house. Appreciate everything you've done this far! Wanted to get something that was a tad bit more mobile-friendly. Open to any feedback/comments/questions/concerns. :) --------- Co-authored-by: BMillerCodes <BMillerCodes@users.noreply.github.com>
This commit is contained in:
co-authored by
BMillerCodes
parent
e4d3a372c8
commit
a9854b1a5c
@@ -105,6 +105,8 @@ def index() -> str:
|
||||
"""
|
||||
return render_template('index.html', book_languages=_SUPPORTED_BOOK_LANGUAGE, default_language=BOOK_LANGUAGE, debug=DEBUG)
|
||||
|
||||
|
||||
|
||||
@app.route('/favico<path:_>')
|
||||
@app.route('/request/favico<path:_>')
|
||||
@app.route('/request/static/favico<path:_>')
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
--table-border-color: #e5e5e5;
|
||||
--input-background: #fff;
|
||||
--heading-color: #333;
|
||||
|
||||
/* Modern UI alias tokens */
|
||||
--bg: var(--background-color);
|
||||
--text: var(--text-color);
|
||||
--border-muted: var(--border-color);
|
||||
--bg-soft: var(--card-background);
|
||||
--footer-bg: var(--header-bg);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
|
||||
+377
-1073
File diff suppressed because it is too large
Load Diff
+179
-220
@@ -3,251 +3,210 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Calibre Web Book Downloader Application">
|
||||
<meta name="description" content="Calibre Web Book Downloader - Modern UI">
|
||||
<meta name="theme-color" content="#333333">
|
||||
<title>Calibre Web Book Downloader</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<!-- Add favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<!-- UIkit CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.21.16/dist/css/uikit.min.css" />
|
||||
<title>Book Downloader • Modern</title>
|
||||
|
||||
<!-- UIkit JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.21.16/dist/js/uikit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.21.16/dist/js/uikit-icons.min.js"></script>
|
||||
<!-- Base styles and theme variables -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='media/favicon.ico') }}">
|
||||
|
||||
<!-- Tailwind (no-build) for rapid iteration) -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle">
|
||||
<h1 class="uk-heading-medium" style="color: white;">Book Search & Download</h1>
|
||||
<div class="uk-margin-right">
|
||||
<body class="min-h-screen" style="background: var(--bg); color: var(--text);">
|
||||
<!-- Header -->
|
||||
<header class="w-full border-b border-[color:var(--border-muted)]" style="background: var(--header-bg);">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<img src="{{ url_for('static', filename='media/logo.png') }}" alt="Logo" class="h-8 w-8">
|
||||
<h1 class="text-lg font-semibold">Book Search & Download</h1>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
{% if debug %}
|
||||
<form action="/api/restart" method="get" style="display: inline;" id="restart-form">
|
||||
<button class="uk-button uk-button-danger uk-margin-small-right" id="restart-button" type="submit">
|
||||
RESTART <span uk-spinner="ratio: 0.8" class="uk-hidden" id="restart-spinner"></span>
|
||||
<form action="/request/api/restart" method="get" id="restart-form">
|
||||
<button class="px-3 py-1 rounded bg-red-600 text-white text-sm" id="restart-button" type="submit">
|
||||
RESTART
|
||||
</button>
|
||||
</form>
|
||||
<form action="/debug" method="get" style="display: inline;" id="debug-form">
|
||||
<button class="uk-button uk-button-danger uk-margin-small-right" id="debug-button" type="submit">
|
||||
DEBUG <span uk-spinner="ratio: 0.8" class="uk-hidden" id="debug-spinner"></span>
|
||||
<form action="/request/debug" method="get" id="debug-form">
|
||||
<button class="px-3 py-1 rounded bg-red-600/80 text-white text-sm" id="debug-button" type="submit">
|
||||
DEBUG
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
<button class="uk-button uk-button-default" type="button" id="theme-toggle">
|
||||
<span uk-icon="icon: paint-bucket"></span>
|
||||
<span id="theme-text">Theme</span>
|
||||
</button>
|
||||
<div uk-dropdown="mode: click">
|
||||
<ul class="uk-nav uk-dropdown-nav">
|
||||
<li><a href="#" data-theme="light">Light</a></li>
|
||||
<li><a href="#" data-theme="dark">Dark</a></li>
|
||||
<li><a href="#" data-theme="auto">Auto (System)</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- Theme Dropdown -->
|
||||
<div class="relative">
|
||||
<button id="theme-toggle" class="px-3 py-1 rounded border text-sm" style="border-color: var(--border-muted);">
|
||||
<span id="theme-text">Theme</span>
|
||||
</button>
|
||||
<div id="theme-menu" class="absolute right-0 mt-2 w-36 rounded-md shadow-lg ring-1 ring-black/5 hidden" style="background: var(--bg-soft);">
|
||||
<ul class="py-1 text-sm">
|
||||
<li><a href="#" data-theme="light" class="block px-3 py-1 hover:bg-black/10">Light</a></li>
|
||||
<li><a href="#" data-theme="dark" class="block px-3 py-1 hover:bg-black/10">Dark</a></li>
|
||||
<li><a href="#" data-theme="auto" class="block px-3 py-1 hover:bg-black/10">Auto (System)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="uk-container">
|
||||
<!-- Search Section -->
|
||||
<section class="uk-section-xxsmall uk-padding">
|
||||
<div class="uk-container uk-width-expand">
|
||||
<form class="uk-search uk-search-default uk-width-expand">
|
||||
<input class="uk-search-input" type="search" placeholder="Search by ISBN, title, author..." aria-label="Search books" id="search-input">
|
||||
<button class="uk-search-icon-flip" uk-search-icon id="search-button" type="button"></button>
|
||||
</form>
|
||||
<button class="uk-button uk-button-default uk-float-right" uk-toggle="target: #search-filters" type="button">Advanced Search</button>
|
||||
<form hidden id="search-filters" class="uk-search uk-search-default uk-inline uk-width-expand uk-flex uk-flex-wrap">
|
||||
<div class="search-filter">
|
||||
<label for="isbn-input">ISBN</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<input class="uk-search-input uk-width-4-5" type="search" placeholder="ISBN..." aria-label="Search by ISBN" id="isbn-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label for="author-input">Author</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<input class="uk-search-input uk-width-4-5" type="search" placeholder="Author..." aria-label="Search by author" id="author-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label for="title-input">Title</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<input class="uk-search-input uk-width-4-5" type="search" placeholder="Title" aria-label="Search by title" id="title-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label for="lang-input">Language</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<select class="uk-select uk-width-4-5" id="lang-input">
|
||||
<option value="all">All</option>
|
||||
{% for lang in book_languages %}
|
||||
<option value="{{ lang.code }}"
|
||||
{% if lang.code == default_language[0] %}selected{% endif %}>
|
||||
{{ lang.language }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label for="sort-input">Sort</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<select class="uk-select uk-width-4-5" id="sort-input">
|
||||
<option value="">Most relevant</option>
|
||||
<option value="newest">Newest (publication year)</option>
|
||||
<option value="oldest">Oldest (publication year)</option>
|
||||
<option value="largest">Largest (filesize)</option>
|
||||
<option value="smallest">Smallest (filesize)</option>
|
||||
<option value="newest_added">Newest (open sourced)</option>
|
||||
<option value="oldest_added">Oldest (open sourced)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label for="content-input">Content</label>
|
||||
<div class="uk-flex uk-flex-wrap">
|
||||
<select class="uk-select uk-width-4-5" id="content-input">
|
||||
<option value="">All</option>
|
||||
<option value="book_nonfiction">Book (non-fiction)</option>
|
||||
<option value="book_fiction">Book (fiction)</option>
|
||||
<option value="book_unknown">Book (unkown)</option>
|
||||
<option value="magazine">Magazine</option>
|
||||
<option value="book_comic">Comic Book</option>
|
||||
<option value="standards_document">Standards document</option>
|
||||
<option value="other">Other</option>
|
||||
<option value="musical_score">Musical score</option>
|
||||
<option value="audiobook">Audiobook</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-filter">
|
||||
<label>Formats</label>
|
||||
<div class="uk-margin uk-grid-small uk-child-width-auto uk-grid">
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-pdf" value="pdf"> PDF</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-epub" value="epub" checked> EPUB</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-mobi" value="mobi" checked> MOBI</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-azw3" value="azw3" checked> AZW3</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-fb2" value="fb2" checked> FB2</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-djvu" value="djvu" checked> DJVU</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-cbz" value="cbz" checked> CBZ</label>
|
||||
<label><input class="uk-checkbox" type="checkbox" id="format-cbr" value="cbr" checked> CBR</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-flex uk-margin-auto-top uk-margin-auto-left">
|
||||
<button class="uk-button uk-button-default uk-margin-small-top" id="adv-search-button" type="button">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<!-- Hero / Search -->
|
||||
<section class="mb-6">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex gap-2">
|
||||
<input id="search-input" type="search" placeholder="Search by ISBN, title, author..." aria-label="Search books"
|
||||
class="flex-1 px-4 py-3 rounded-md border outline-none"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
<button id="search-button" class="px-4 py-3 rounded-md text-white bg-blue-600 hover:bg-blue-700">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Results Section -->
|
||||
<ul uk-accordion="animation: false" id="results-section-accordion">
|
||||
<li id="search-accordion">
|
||||
<a class="uk-accordion-title" href><h1 class="uk-heading-xsmall">Search Results</h1></a>
|
||||
<div class="uk-accordion-content">
|
||||
<div id="search-loading" class="uk-flex uk-flex-center" role="status" hidden>
|
||||
<div uk-spinner="ratio: 2"></div>
|
||||
<span>Loading...</span>
|
||||
<div>
|
||||
<button id="toggle-advanced" class="text-sm underline opacity-80 hover:opacity-100">Advanced Search</button>
|
||||
</div>
|
||||
<!-- Advanced Filters -->
|
||||
<form id="search-filters" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 hidden">
|
||||
<div>
|
||||
<label for="isbn-input" class="block text-sm mb-1 opacity-80">ISBN</label>
|
||||
<input id="isbn-input" type="search" placeholder="ISBN"
|
||||
class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
</div>
|
||||
<div class="results-content">
|
||||
<button class="uk-button uk-button-primary uk-margin-small" id="download-selected-button" disabled>Download Selected</button>
|
||||
<div class="uk-overflow-auto">
|
||||
<table id="results-table" class="uk-table uk-table-hover uk-table-divider" role="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<input type="checkbox" id="select-all-checkbox" class="uk-checkbox" />
|
||||
</th>
|
||||
<th scope="col" data-sort="index"># <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col">Preview</th>
|
||||
<th scope="col" data-sort="title">Title <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="author">Author <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="publisher">Publisher <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="year">Year <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="language">Language <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="format">Format <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col" data-sort="size">Size <span class="sort-icon" uk-icon></span></th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Search results will be injected here -->
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<label for="author-input" class="block text-sm mb-1 opacity-80">Author</label>
|
||||
<input id="author-input" type="search" placeholder="Author"
|
||||
class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
</div>
|
||||
<div>
|
||||
<label for="title-input" class="block text-sm mb-1 opacity-80">Title</label>
|
||||
<input id="title-input" type="search" placeholder="Title"
|
||||
class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
</div>
|
||||
<div>
|
||||
<label for="lang-input" class="block text-sm mb-1 opacity-80">Language</label>
|
||||
<select id="lang-input" class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
<option value="all">All</option>
|
||||
{% for lang in book_languages %}
|
||||
<option value="{{ lang.code }}" {% if lang.code == default_language[0] %}selected{% endif %}>
|
||||
{{ lang.language }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="sort-input" class="block text-sm mb-1 opacity-80">Sort</label>
|
||||
<select id="sort-input" class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
<option value="">Most relevant</option>
|
||||
<option value="newest">Newest (publication year)</option>
|
||||
<option value="oldest">Oldest (publication year)</option>
|
||||
<option value="largest">Largest (filesize)</option>
|
||||
<option value="smallest">Smallest (filesize)</option>
|
||||
<option value="newest_added">Newest (open sourced)</option>
|
||||
<option value="oldest_added">Oldest (open sourced)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="content-input" class="block text sm mb-1 opacity-80">Content</label>
|
||||
<select id="content-input" class="w-full px-3 py-2 rounded-md border"
|
||||
style="background: var(--bg-soft); color: var(--text); border-color: var(--border-muted);">
|
||||
<option value="">All</option>
|
||||
<option value="book_nonfiction">Book (non-fiction)</option>
|
||||
<option value="book_fiction">Book (fiction)</option>
|
||||
<option value="book_unknown">Book (unknown)</option>
|
||||
<option value="magazine">Magazine</option>
|
||||
<option value="book_comic">Comic Book</option>
|
||||
<option value="standards_document">Standards document</option>
|
||||
<option value="other">Other</option>
|
||||
<option value="musical_score">Musical score</option>
|
||||
<option value="audiobook">Audiobook</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="md:col-span-2 lg:col-span-3">
|
||||
<label class="block text-sm mb-1 opacity-80">Formats</label>
|
||||
<div class="flex flex-wrap gap-3 text-sm">
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-pdf" value="pdf"> PDF</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-epub" value="epub" checked> EPUB</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-mobi" value="mobi" checked> MOBI</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-azw3" value="azw3" checked> AZW3</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-fb2" value="fb2" checked> FB2</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-djvu" value="djvu" checked> DJVU</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-cbz" value="cbz" checked> CBZ</label>
|
||||
<label class="inline-flex items-center gap-2"><input type="checkbox" id="format-cbr" value="cbr" checked> CBR</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="md:col-span-2 lg:col-span-3 flex justify-end">
|
||||
<button id="adv-search-button" type="button" class="px-4 py-2 rounded-md border"
|
||||
style="border-color: var(--border-muted);">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal-overlay" id="modal-overlay" role="dialog" aria-modal="true">
|
||||
<div class="details-container" id="details-container">
|
||||
<!-- Details will be dynamically injected here -->
|
||||
<!-- Active Downloads (Top) -->
|
||||
<section id="active-downloads-top" class="mb-6 hidden">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h2 class="text-lg font-semibold">Active Downloads</h2>
|
||||
<button id="active-refresh-button" class="px-3 py-1 rounded border text-sm" style="border-color: var(--border-muted);">Refresh</button>
|
||||
</div>
|
||||
<div id="active-downloads-list" class="space-y-2"></div>
|
||||
</section>
|
||||
|
||||
<!-- Results -->
|
||||
<section class="mb-8">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h2 class="text-xl font-semibold">Search Results</h2>
|
||||
<div id="search-loading" class="text-sm opacity-80 hidden">Loading…</div>
|
||||
</div>
|
||||
<div id="results-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||
<!-- Cards will be injected here -->
|
||||
</div>
|
||||
<div id="no-results" class="mt-4 text-sm opacity-80 hidden">No results found.</div>
|
||||
</section>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal-overlay" id="modal-overlay" role="dialog" aria-modal="true">
|
||||
<div class="details-container" id="details-container"></div>
|
||||
</div>
|
||||
|
||||
<!-- Status -->
|
||||
<section>
|
||||
<div class="flex items-center flex-wrap mb-3">
|
||||
<h2 class="text-xl font-semibold mr-4 sm:mr-6">Download Queue & Status</h2>
|
||||
<div class="flex items-center gap-3 ml-4 sm:ml-auto">
|
||||
<button id="refresh-status-button" class="px-3 py-1 rounded border text-sm" style="border-color: var(--border-muted);">Refresh</button>
|
||||
<button id="clear-completed-button" class="px-3 py-1 rounded border text-sm" style="border-color: var(--border-muted);">Clear Completed</button>
|
||||
<span id="active-downloads-count" class="text-sm opacity-80">Active: 0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status Section -->
|
||||
<ul uk-accordion="animation: false" id="status-section">
|
||||
<li id="search-accordion">
|
||||
<a class="uk-accordion-title" href><h1 class="uk-heading-xsmall">Download Queue & Status</h1></a>
|
||||
<div class="uk-accordion-content">
|
||||
<div id="status-loading" class="uk-flex uk-flex-center" role="status" hidden>
|
||||
<div uk-spinner="ratio: 2"></div>
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
<div class="status-content">
|
||||
<div class="uk-overflow-auto">
|
||||
<!-- Queue Management Controls -->
|
||||
<div class="uk-margin-small-bottom">
|
||||
<div class="uk-flex uk-flex-between uk-flex-wrap uk-flex-middle">
|
||||
<div class="uk-flex uk-flex-wrap uk-flex-middle">
|
||||
<button class="uk-button uk-button-default uk-button-small uk-margin-small-right" id="refresh-status-button">
|
||||
<span uk-icon="icon: refresh"></span> Refresh
|
||||
</button>
|
||||
<button class="uk-button uk-button-secondary uk-button-small uk-margin-small-right" id="clear-completed-button">
|
||||
<span uk-icon="icon: trash"></span> Clear Completed
|
||||
</button>
|
||||
<span class="uk-text-small uk-text-muted uk-margin-small-right" id="active-downloads-count">Active: 0</span>
|
||||
</div>
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<label class="uk-text-small uk-margin-small-right">Max Concurrent:</label>
|
||||
<span class="uk-text-small uk-text-bold" id="max-concurrent-display">3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="status-table" class="uk-table uk-table-hover uk-table-divider uk-table-small" role="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Priority</th>
|
||||
<th scope="col">Title</th>
|
||||
<th scope="col">Progress</th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Search results will be injected here -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="status-loading" class="text-sm opacity-80 hidden">Loading…</div>
|
||||
<div id="status-list" class="space-y-2"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<h1 class="uk-heading-xxsmall" style="color: white;">Calibre Web Book Downloader</h1>
|
||||
<a href="https://github.com/calibrain/calibre-web-automated-book-downloader" class="uk-icon-link" uk-icon="icon:github; ratio: 2"></a>
|
||||
<footer class="mt-10 border-t pt-6 pb-10" style="border-color: var(--border-muted); background: var(--footer-bg);">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
|
||||
<p class="text-sm opacity-80">Calibre Web Book Downloader</p>
|
||||
<a href="https://github.com/calibrain/calibre-web-automated-book-downloader" class="opacity-80 hover:opacity-100" aria-label="GitHub">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8a8 8 0 005.47 7.59c.4.07.55-.17.55-.38
|
||||
0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52
|
||||
-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95
|
||||
0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.54 7.54 0 012 0c1.53-1.03 2.2-.82 2.2-.82
|
||||
.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2
|
||||
0 .21.15.46.55.38A8 8 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="{{ url_for('static', filename='js/main.js') }}" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user