feat(ui): add /browse page and /api/scrape proxy route
- /browse calls GET /api/browse on the scraper and renders a novel grid mirroring the novelfire layout: cover, rank/rating badges, chapter count, genre/sort/status filters, and pagation controls - Scrape buttons are shown only to admin users; clicking enqueues the book via /api/scrape - /api/scrape is an admin-only SvelteKit server route that proxies POST requests to the Go scraper's /scrape/book or /scrape endpoints; returns 403 for non-admins
This commit is contained in:
47
ui/src/routes/browse/+page.server.ts
Normal file
47
ui/src/routes/browse/+page.server.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { env } from '$env/dynamic/private';
|
||||
|
||||
const SCRAPER_URL = env.SCRAPER_API_URL ?? 'http://localhost:8080';
|
||||
|
||||
export interface NovelListing {
|
||||
slug: string;
|
||||
title: string;
|
||||
cover: string;
|
||||
rank: string;
|
||||
rating: string;
|
||||
chapters: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = async ({ url, locals }) => {
|
||||
const page = url.searchParams.get('page') ?? '1';
|
||||
const genre = url.searchParams.get('genre') ?? 'all';
|
||||
const sort = url.searchParams.get('sort') ?? 'popular';
|
||||
const status = url.searchParams.get('status') ?? 'all';
|
||||
|
||||
const params = new URLSearchParams({ page, genre, sort, status });
|
||||
const apiURL = `${SCRAPER_URL}/api/browse?${params.toString()}`;
|
||||
|
||||
let data: { novels: NovelListing[]; page: number; hasNext: boolean };
|
||||
try {
|
||||
const res = await fetch(apiURL);
|
||||
if (!res.ok) {
|
||||
throw error(502, `Browse fetch failed: ${res.status}`);
|
||||
}
|
||||
data = await res.json();
|
||||
} catch (e) {
|
||||
if (e instanceof Error && 'status' in e) throw e;
|
||||
throw error(502, 'Could not load browse page');
|
||||
}
|
||||
|
||||
return {
|
||||
novels: data.novels ?? [],
|
||||
page: data.page ?? 1,
|
||||
hasNext: data.hasNext ?? false,
|
||||
genre,
|
||||
sort,
|
||||
status,
|
||||
isAdmin: locals.user?.role === 'admin'
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user