diff --git a/ui/src/routes/admin/+layout.svelte b/ui/src/routes/admin/+layout.svelte
index 671a64c..e6b5c96 100644
--- a/ui/src/routes/admin/+layout.svelte
+++ b/ui/src/routes/admin/+layout.svelte
@@ -3,7 +3,8 @@
const internalLinks = [
{ href: '/admin/scrape', label: 'Scrape' },
- { href: '/admin/audio', label: 'Audio' }
+ { href: '/admin/audio', label: 'Audio' },
+ { href: '/admin/changelog', label: 'Changelog' }
];
const externalLinks = [
diff --git a/ui/src/routes/admin/changelog/+page.server.ts b/ui/src/routes/admin/changelog/+page.server.ts
new file mode 100644
index 0000000..a47ad03
--- /dev/null
+++ b/ui/src/routes/admin/changelog/+page.server.ts
@@ -0,0 +1,27 @@
+import type { PageServerLoad } from './$types';
+
+export interface Release {
+ id: number;
+ tag_name: string;
+ name: string;
+ body: string;
+ published_at: string;
+ prerelease: boolean;
+ draft: boolean;
+}
+
+export const load: PageServerLoad = async ({ fetch }) => {
+ try {
+ const res = await fetch(
+ 'https://gitea.kalekber.cc/api/v1/repos/kamil/libnovel/releases?limit=50&page=1',
+ { headers: { Accept: 'application/json' } }
+ );
+ if (!res.ok) throw new Error(`Gitea API returned ${res.status}`);
+ const releases: Release[] = await res.json();
+ return {
+ releases: releases.filter((r) => !r.draft)
+ };
+ } catch (e) {
+ return { releases: [], error: String(e) };
+ }
+};
diff --git a/ui/src/routes/admin/changelog/+page.svelte b/ui/src/routes/admin/changelog/+page.svelte
new file mode 100644
index 0000000..eae4134
--- /dev/null
+++ b/ui/src/routes/admin/changelog/+page.svelte
@@ -0,0 +1,59 @@
+
+
+
Could not load releases: {data.error}
+ {:else if data.releases.length === 0} +No releases found.
+ {:else} +{release.body.trim()}
+ {/if} +- Job status: - {#if running} - Running - {:else} - Idle - {/if} -
-Re-crawls all novelfire.net pages and picks up new books.
-{catalogueError}
- {/if} + {#if catalogueError}{catalogueError}{/if}{scrapeError}
- {/if} +{rangeError}
- {/if} -Paste one of these into the single-book scraper to re-index a genre, or use them as starting points for range scrapes.
- + + +